C4 Engine Wiki c4_wiki https://c4engine.com/wiki/index.php?title=Main_Page MediaWiki 1.40.0 first-letter Media Special Talk User User talk C4 Engine Wiki C4 Engine Wiki talk File File talk MediaWiki MediaWiki talk Template Template talk Help Help talk Category Category talk Main Page 0 1 1 2023-07-15T02:02:30Z MediaWiki default 2 wikitext text/x-wiki <strong>MediaWiki has been installed.</strong> Consult the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents User's Guide] for information on using the wiki software. == Getting started == * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ] * [https://lists.wikimedia.org/postorius/lists/mediawiki-announce.lists.wikimedia.org/ MediaWiki release mailing list] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language] * [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki] 11cef88175cf81168a86e7c0327a5b2d7a1920f5 2 1 2023-07-15T08:58:41Z Eric Lengyel 1 wikitext text/x-wiki __NOTOC__ {| style="width: 100%; border: 0px;" | style="width: 50%; vertical-align: top; padding-right: 10%;" | == General == * [[General Information for Licensed Users]] * [[Getting Started]] * [[Quick Tour]] * [[Programming Introduction]] * [[Glossary]] * [[Release Notes]] == Engine == * [[C4 Menu]] * [[Command Console]] * [[Pack Files and Virtual Directories]] * [[File Locations]] * [[String Tables]] === Controllers === * [[Movement Controller]] * [[Oscillation Controller]] * [[Rotation Controller]] * [[Spin Controller]] * [[Rope Controller]] * [[Cloth Controller]] * [[Rigid Body Controller]] * [[Physics Controller]] * [[Animation Controller]] * [[Distribution Controller]] === Custom Classes === * [[Defining a Custom Controller]] * [[Defining a Custom Method]] == Concepts == * [[The C4 Rendering Pipeline]] * [[Models and Instanced Worlds]] * [[Cascaded Shadow Mapping]] * [[Motion Blur]] * [[Fog Spaces]] | style="width: 50%; vertical-align: top; padding-right: 10%;" | == Tools == * [[World Editor]] ** [[World Editor Pages]] ** [[Connectors]] ** [[Modifiers]] * [[Material Editor]] * [[Shader Editor]] ** [[Basic Shader Processes]] ** [[Mathematical Shader Processes]] ** [[Complex Shader Processes]] ** [[Interpolant Shader Processes]] * [[Script Editor]] ** [[Methods]] ** [[Expression Evaluation in Scripts]] * [[Panel Editor]] ** [[Widgets]] ** [[Text Formatting]] * [[Landscaping Editor]] * [[Model Viewer]] * [[Texture Viewer]] * [[Texture Importer]] * [[Font Importer]] * [[Sound Player]] * [[Sound Importer]] * [[Movie Player]] * [[Movie Importer]] * [[String Importer]] * [[Resource Packer]] == Tutorials == * [[New World Tutorial]] * [[Portal Tutorial]] * [[Oscillation Tutorial]] * [[Terrain Tutorial]] * [[Water Tutorial]] * [[Teleport Tutorial]] * [[Simple Games]] |} be2100e74ef58b3d769e4d25707b9159b3201f86 3 2 2023-07-15T09:02:37Z Eric Lengyel 1 /* General */ wikitext text/x-wiki __NOTOC__ {| style="width: 100%; border: 0px;" | style="width: 50%; vertical-align: top; padding-right: 10%;" | == General == * [[Getting Started]] * [[Quick Tour]] * [[Programming Introduction]] * [[Glossary]] * [[Release Notes]] == Engine == * [[C4 Menu]] * [[Command Console]] * [[Pack Files and Virtual Directories]] * [[File Locations]] * [[String Tables]] === Controllers === * [[Movement Controller]] * [[Oscillation Controller]] * [[Rotation Controller]] * [[Spin Controller]] * [[Rope Controller]] * [[Cloth Controller]] * [[Rigid Body Controller]] * [[Physics Controller]] * [[Animation Controller]] * [[Distribution Controller]] === Custom Classes === * [[Defining a Custom Controller]] * [[Defining a Custom Method]] == Concepts == * [[The C4 Rendering Pipeline]] * [[Models and Instanced Worlds]] * [[Cascaded Shadow Mapping]] * [[Motion Blur]] * [[Fog Spaces]] | style="width: 50%; vertical-align: top; padding-right: 10%;" | == Tools == * [[World Editor]] ** [[World Editor Pages]] ** [[Connectors]] ** [[Modifiers]] * [[Material Editor]] * [[Shader Editor]] ** [[Basic Shader Processes]] ** [[Mathematical Shader Processes]] ** [[Complex Shader Processes]] ** [[Interpolant Shader Processes]] * [[Script Editor]] ** [[Methods]] ** [[Expression Evaluation in Scripts]] * [[Panel Editor]] ** [[Widgets]] ** [[Text Formatting]] * [[Landscaping Editor]] * [[Model Viewer]] * [[Texture Viewer]] * [[Texture Importer]] * [[Font Importer]] * [[Sound Player]] * [[Sound Importer]] * [[Movie Player]] * [[Movie Importer]] * [[String Importer]] * [[Resource Packer]] == Tutorials == * [[New World Tutorial]] * [[Portal Tutorial]] * [[Oscillation Tutorial]] * [[Terrain Tutorial]] * [[Water Tutorial]] * [[Teleport Tutorial]] * [[Simple Games]] |} 709cd0bb45d2b2d45b48dd55f333faebae55cee3 Getting Started 0 2 4 2023-07-15T09:04:34Z Eric Lengyel 1 Created page with "__NOTOC__ === Installation === Follow these instructions to get started with the C4 Engine under 64-bit Windows 10. To install, first create a directory somewhere on your hard drive in which you'll store all of the C4 Engine files. Put the source code in this directory and extract the C4-Data-xxx.zip file into the same directory. Your C4 Engine directory should look like the following: * Data * EngineCode * GameCode * Import * PluginCode * SimpleCode * SlugCode * Tera..." wikitext text/x-wiki __NOTOC__ === Installation === Follow these instructions to get started with the C4 Engine under 64-bit Windows 10. To install, first create a directory somewhere on your hard drive in which you'll store all of the C4 Engine files. Put the source code in this directory and extract the C4-Data-xxx.zip file into the same directory. Your C4 Engine directory should look like the following: * Data * EngineCode * GameCode * Import * PluginCode * SimpleCode * SlugCode * TerathonCode * VisualStudio-win === Building === The C4 Engine can be built with Visual Studio 2022. This can be downloaded from the following location: [https://visualstudio.microsoft.com/downloads/ Microsoft Visual Studio Download] If you haven't already done so, you will need to install the DirectX SDK in order to build the C4 Engine. It can be downloaded here: [https://www.microsoft.com/en-us/download/details.aspx?id=6812 DirectX SDK] The project files for Visual Studio are located at the following place inside the C4 Engine folder. <code>VisualStudio/C4/C4.sln</code> After opening the solution file in Visual Studio, select "Build Solution" from the Build menu to build the engine. This will cause several binaries to be built: <code>C4.exe</code>, <code>The31st.dll</code>, and a bunch of DLLs that get stored in the <code>Plugins</code> directory. === Running === To run the C4 Engine, double-click on the <code>C4Engine.exe</code> application. You can also run from inside Visual Studio. '''Tip:''' When running from the Visual Studio debugger, Windows automatically enables memory heap debugging features that are used by the entire process being debugged, including external libraries such as the graphics drivers. This can cause significant delays that do not appear when not running in the debugger. To disable these debugging features, set the Environment property in the Debugging page to <code>_NO_DEBUG_HEAP=1</code>. == See Also == * [[Quick Tour]] 452989f90840cacb1b5e5e16dd291ea5017a0e7c Quick Tour 0 3 5 2023-07-15T09:06:44Z Eric Lengyel 1 Created page with "This article describes what you'll see when you run the C4 Engine for the first time after building the engine with the stock project files and data. == Basic Interface == By default, the C4 Engine is configured to start up in the demo game called ''The 31st''. (This is a game currently in development at Terathon Software.) The demo game's title screen appears as shown in the background of the screenshot below. All of the settings that can be accessed from this title s..." wikitext text/x-wiki This article describes what you'll see when you run the C4 Engine for the first time after building the engine with the stock project files and data. == Basic Interface == By default, the C4 Engine is configured to start up in the demo game called ''The 31st''. (This is a game currently in development at Terathon Software.) The demo game's title screen appears as shown in the background of the screenshot below. All of the settings that can be accessed from this title screen are fully functional and can be used to configure things like the graphics options used by the engine. Like many engines, the C4 Engine contains a command console that can be accessed by pressing the key directly below the Escape key on the keyboard. On English keyboard layouts, this key types a tilde or grave accent. If you press this key to open the console from the title screen, then you should see everything in the following screenshot. [[Image:Quicktour.png|960px]] The [[Command Console]] is the window that opens in the upper-left corner of the screen. It displays the version of the engine upon startup. When a window like the console is opened, the "strip" also appears at the bottom of the screen. The strip behaves like the taskbar under Windows and contains buttons for each of the major user interface windows that are open inside the engine. The strip also contains the [[C4 Menu]] in the lower-left corner of the screen that is analogous to the Windows Start menu. This menu contains commands for opening utility windows, quitting the engine, and accessing tool plugins as described in the [[C4 Menu]] article. == Quitting == The C4 Engine can be closed in a number of ways: * If you're running in windowed mode, then you can click the close box of the OS window containing C4. Note that you can only do this when you see a cursor, and this is the case only when a major engine window is open, like the [[Command Console]] or [[World Editor]]. * Choose the '''Quit''' command from the [[C4 Menu]], as described in the previous section. You can also type Ctrl-Q, but only when a major engine window is open. If a game is being played, you don't want the combination of the control key and the Q key to quit because the user may have bound those to different actions in the game that could be used simultaneously. * Type <code>quit</code> in the [[Command Console]]. == See Also == * [[Getting Started]] b1c73e34fed5c819dafb289ebd8bfe97fd85f524 File:Quicktour.png 6 4 6 2023-07-15T09:08:17Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Architecture.png 6 5 7 2023-07-15T09:10:19Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Programming Introduction 0 6 8 2023-07-15T09:10:27Z Eric Lengyel 1 Created page with "This page provides an introduction to the programming interface and general design philosophies of the C4 Engine. An understanding of each of the topics described below is essential to programming applications for the C4 Engine effectively. Specific information about the application programming interface (API) is not covered here, but instead can be found in the [http://c4engine.com/docs/ API Documentation]. == Engine Architecture == File:Architecture.png|right|thumb..." wikitext text/x-wiki This page provides an introduction to the programming interface and general design philosophies of the C4 Engine. An understanding of each of the topics described below is essential to programming applications for the C4 Engine effectively. Specific information about the application programming interface (API) is not covered here, but instead can be found in the [http://c4engine.com/docs/ API Documentation]. == Engine Architecture == [[File:Architecture.png|right|thumb|640px|'''Figure 1.''' [http://c4engine.com/ The C4 Engine architecture.]]] The main parts of the C4 Engine are made up of a collection of ''managers'', each of which provides a specific type of functionality. The managers are arranged in a layered architecture as shown in Figure 1. (Click on the caption for a larger image.) Managers providing high-level functionality depend on other managers that provide low-level functionality. The lowest level managers are the only parts of the engine that interact directly with the operating system, and the layers above them are completely platform independent. The low-level managers include the Sound Manager, the Network Manager, and the Input Manager. These managers utilize the lightest-weight interfaces for audio, networking, and input devices available on each platform supported by the engine. A platform-neutral API is then provided to the rest of the engine and to the game code. The engine also provides many low-level services that are platform-independent, and these include a containers library, math library, and built-in support for the [[Open Data Description Language]] (OpenDDL). Specific applications and tools are built as dynamic-link libraries (DLLs) that are separate from the C4 Engine and loaded as plugins. This separation between the main engine module and other modules cleanly isolates the application-independent code in the engine. It also allows an application or tool to be rebuilt without having to recompile the engine. When the C4 Engine is run, it loads at most one application module and any number of tool modules. The C4 Engine ships with several plugins that provide specific tools for building games. The largest plugin module is the [[World Editor]], which is used to construct levels in a development environment that runs on top of the engine's own user interface system. The editor itself supports plugins, and one type of plugin is an importer that can bring in modeling data from external sources. The preferred format used by the World Editor is the [[Open Game Engine Exchange]] (OpenGEX) format, but the editor also includes a plugin that can read Collada files. == Nodes == A single scene that can be rendered in the C4 Engine is called a ''world'' and is represented by the <code>[http://c4engine.com/docs/WorldMgr/World.html World]</code> class. All of the items in a world are organized into a scene graph having a tree structure, and each node of this tree represents a single item. The C4 Engine defines a class called <code>[http://c4engine.com/docs/WorldMgr/Node.html Node]</code> that serves as the base class for a [http://c4engine.com/docs/WorldMgr/Node_tree.html large hierarchy of different classes] used to represent a variety of different types of objects in the scene graph. Some examples of various node types and their associated classes are listed below. * '''Lights.''' There are several distinct light types supported by the C4 Engine, and they are represented by the <code>[http://c4engine.com/docs/WorldMgr/Light.html Light]</code> class. * '''Cameras.''' Although only one type of camera is ordinarily used, the C4 Engine supports a few different types of cameras. They are represented by the <code>[http://c4engine.com/docs/WorldMgr/Camera.html Camera]</code> class. * '''Geometries.''' Most polygonal geometry is encapsulated in the scene graph by the <code>[http://c4engine.com/docs/WorldMgr/Geometry.html Geometry]</code> class. * '''Sources.''' Sound sources can be placed in the scene graph, and they are represented by the <code>[http://c4engine.com/docs/WorldMgr/Source.html Source]</code> class. * '''Zones.''' Every world is divided into one or more zones, which can overlap and be arranged hierarchically. Zones are represented by the <code>[http://c4engine.com/docs/WorldMgr/Zone.html Zone]</code> class. * '''Portals.''' Zones are connected by portals, represented by the <code>[http://c4engine.com/docs/WorldMgr/Portal.html Portal]</code> class. A node can have any number of subnodes, and all nodes except the root node of the scene have exactly one supernode. Each node contains a transformation matrix that describes how coordinates are transformed from its local coordinate space to the coordinate space of its supernode. Each node also contains the transformation from its local space all the way to world space. == Objects, Controllers, and Properties == There are a number of auxiliary data structures that can be referenced by any particular node. For most types of nodes, there are corresponding types of ''objects''. A node can reference only one object corresponding to its primary type (some types of nodes also reference additional special objects), but an object can be referenced by an unlimited number of nodes. This is how data instancing works in the C4 Engine. All instance-specific information (such as a transform) is stored in a <code>Node</code> subclass, and all information that is shared among all instances is stored in an <code>Object</code> subclass. The [http://c4engine.com/docs/WorldMgr/Object_tree.html hierarchy of object classes] is similar to that of nodes. Each node in a scene graph may have a ''controller'' attached to it. A controller is represented by the <code>[http://c4engine.com/docs/Controller/Controller.html Controller]</code> class and is used to manage anything about its target node that changes over time. For example, a controller could be used to move a geometry node in some way, or it could be used to modify the brightness of a light source. Several types of controllers are built into the core engine, and an application can define its own types of controllers by subclassing from the <code>Controller</code> class. A node may have any number of ''properties'' attached to it that define any special characteristics that the node possesses. There are a few property classes built into the core engine, but most properties are defined by an application. A single subclass of the <code>[http://c4engine.com/docs/WorldMgr/Property.html Property]</code> class can hold any amount of information, and an application can define a user interface for adjusting this information in the [[World Editor]]. == See Also == * [[Glossary]] 6a77133e167225a2e05be83f6e2afec0e0d747e5 Glossary 0 7 9 2023-07-15T09:11:51Z Eric Lengyel 1 Created page with "__NOTOC__ This glossary defines many of the terms that are used by the C4 Engine and provides links to more information in most cases. == B == '''Blocker''' A blocker is a volume of space that can be used to block the passage of a rope or cloth geometry. == C == '''Controller''' A controller is attached to a node in order to manage some kind of motion or behavior. Controllers also serve as the point where scripts can interact with nodes and where network communicatio..." wikitext text/x-wiki __NOTOC__ This glossary defines many of the terms that are used by the C4 Engine and provides links to more information in most cases. == B == '''Blocker''' A blocker is a volume of space that can be used to block the passage of a rope or cloth geometry. == C == '''Controller''' A controller is attached to a node in order to manage some kind of motion or behavior. Controllers also serve as the point where scripts can interact with nodes and where network communications take place. == D == '''Detail Ring''' A detail ring corresponds to a distance from the camera inside which objects belonging to the ring are rendered. See [[Detail Rings]]. == F == '''FGED''' An acronym for ''Foundations of Game Engine Development'', a series of books by Eric Lengyel. See [[FGED]]. '''Fiber''' A fiber represents the connection between two methods in a script. See [[Script Editor]]. '''Field''' A field is a volume of space that can exert a force in the physics simulation. See [[Physics]]. '''Force''' A force is attached to a field in order to generate some kind of force in the physics simulation. See [[Physics]]. '''Function''' A function is an operation that can be defined by a controller to available for use in a script. See [[Script Editor]]. == G == '''Geometry''' A geometry is a node that contains a triangle mesh used for rendering and/or collision detection in a world. == I == '''Illuminance Space''' An illuminance space is a volume inside which indirect lighting information is stored for realistic illumination of both static and dynamic objects. '''Impostor''' An impostor is a two-dimensional representation of a complex three-dimensional object. The impostor is rendered when the camera is far from the object to increase performance. See [[Impostors]]. == J == '''Joint''' A joint places constrains on one or two rigid bodies so that they are forced to move in a specific way. See [[Physics]]. == M == '''Material''' A material defines the appearance of a geometry or other rendered object. It can be created through a set of standard attributes or with a custom shader. See [[Material Editor]]. '''Method''' A method is single component of a script, and it performs a specific operation. See [[Script Editor]]. '''Model''' A model is a hierarchy of nodes that represents some entity in a game, such as a character or vehicle. See [[Models]]. '''Modifier''' A modifier is an operation that can be assigned to an instanced world, and it performs some kind of modification on that world when the world is loaded. See [[Modifiers]]. == N == '''Node''' A node is a single element of a world, such as a geometry, light, sound source, trigger, special effect, etc. See [[World Editor]]. == P == '''Paint Space''' A paint space is a volume of space inside which a 2D paint texture can be projected onto geometries. '''Panel Effect''' A panel effect is a user interface panel that can appear inside a world. It contains a collection of widgets. See [[Panel Editor]]. '''Physics Space''' A physics space is a volume that defines the spatial limits of the physics simulation. Rigid bodies are automatically destroyed if they leave the physics space. See [[Physics]]. '''Portal''' A portal defines a polygonal area through which one zone can be seen from another zone. Portals are a component of the primary visibility system in the C4 Engine. See [[Zones and Portals]]. '''Process''' A process is a single component of a shader, and it performs a specific operation. See [[Shader Editor]]. == R == '''Rigid Body''' A rigid body is the primary type of object managed by the physics simulation. A rigid body is composed of one or more shapes. See [[Physics]]. '''Route''' A route represents the connection between two processes in a shader. See [[Shader Editor]]. == S == '''Shadow Space''' A shadow space is a volume that defines the spatial limits of the shadows cast by one of more light sources. The use of shadow spaces is an optimization that allows the engine to render fewer shadow castors in many situations. '''Shape''' A single component of a rigid body, defining its geometry as it pertains to the physics simulation. See [[Physics]]. '''Slug''' The Slug Library is the font and vector graphics rendering technology used to draw text and icons. See [[Slug Library]]. '''Source''' A source represents a sound that can be played in a world. '''Sprocket''' A sprocket is an operation that can be assigned to a widget, and it changes the widget in some way over time. See [[Sprockets]]. '''SSAO''' SSAO is an acronym for Screen-Space Ambient Occlusion, and it is a postprocessing effect that reduces ambient light levels in creases and corners to create the appearance of more realistic ambient lighting. == T == '''Trigger''' A trigger is a volume of space that causes some action to be taken whenever a model enters or exits it. == W == '''Widget''' A widget is a single component of a user interface, such as a check box or slider. See [[Widgets]]. '''World''' A world is a playable level in the C4 Engine. A level can be composed of a primary world and many smaller instanced worlds that are loaded from separate resources. See [[World Editor]]. == Z == '''Zone''' A zone is a volume of space that represents the largest unit of visibility in a world. Zones are a component of the primary visibility system in the C4 Engine. See [[Zones and Portals]]. a547c4a4f45f1afca4d404ecd0a49202bd88bf6d Release Notes 0 8 10 2023-07-15T09:13:45Z Eric Lengyel 1 Created page with "__NOTOC__ == Version 7.x == {| {{Table}} {{Tablehead3|Version|Release Date|Release Notes}} |- {{Tablerow3|Version 7.1|24 April 2023|[[Release Notes for Version 7.1]]}} |- {{Tablerow3|Version 7.0|22 March 2023|[[Release Notes for Version 7.0]]}} |} == Version 6.x == {| {{Table}} {{Tablehead3|Version|Release Date|Release Notes}} |- {{Tablerow3|Version 6.9|2 Nov 2018|[[Release Notes for Version 6.9]]}} |- {{Tablerow3|Version 6.5|30 Sep 2017|Release Notes for Version 6...." wikitext text/x-wiki __NOTOC__ == Version 7.x == {| {{Table}} {{Tablehead3|Version|Release Date|Release Notes}} |- {{Tablerow3|Version 7.1|24 April 2023|[[Release Notes for Version 7.1]]}} |- {{Tablerow3|Version 7.0|22 March 2023|[[Release Notes for Version 7.0]]}} |} == Version 6.x == {| {{Table}} {{Tablehead3|Version|Release Date|Release Notes}} |- {{Tablerow3|Version 6.9|2 Nov 2018|[[Release Notes for Version 6.9]]}} |- {{Tablerow3|Version 6.5|30 Sep 2017|[[Release Notes for Version 6.5]]}} |- {{Tablerow3|Version 6.2|11 May 2017|[[Release Notes for Version 6.2]]}} |- {{Tablerow3|Version 6.1|29 Apr 2017|[[Release Notes for Version 6.1]]}} |- {{Tablerow3|Version 6.0|27 Jan 2017|[[Release Notes for Version 6.0]]}} |} == Version 5.x == {| {{Table}} {{Tablehead3|Version|Release Date|Release Notes}} |- {{Tablerow3|Version 5.5.1|6 Dec 2016|[[Release Notes for Version 5.5.1]]}} |- {{Tablerow3|Version 5.5|16 Nov 2016|[[Release Notes for Version 5.5]]}} |- {{Tablerow3|Version 5.0|20 Sep 2016|[[Release Notes for Version 5.0]]}} |} == Version 4.x == {| {{Table}} {{Tablehead3|Version|Release Date|Release Notes}} |- {{Tablerow3|Version 4.5|28 Mar 2015|[[Release Notes for Version 4.5]]}} |- {{Tablerow3|Version 4.2|11 Jan 2015|[[Release Notes for Version 4.2]]}} |- {{Tablerow3|Version 4.1|25 Dec 2014|[[Release Notes for Version 4.1]]}} |- {{Tablerow3|Version 4.0|14 Oct 2014|[[Release Notes for Version 4.0]]}} |} == Version 3.x == {| {{Table}} {{Tablehead3|Version|Release&nbsp;Date|Release Notes}} |- {{Tablerow3|Version 3.5.1|22 Jan 2014|[[Release Notes for Version 3.5.1]]}} |- {{Tablerow3|Version 3.5|8 Jan 2014|[[Release Notes for Version 3.5]]}} |- {{Tablerow3|Version 3.0|29 Jul 2013|[[Release Notes for Version 3.0]]}} |} == Version 2.x == {| {{Table}} {{Tablehead3|Version|Release&nbsp;Date|Release Notes}} |- {{Tablerow3|Version 2.10.3|31 Mar 2013|[[Release Notes for Version 2.10.3]]}} |- {{Tablerow3|Version 2.10.2|7 Mar 2013|[[Release Notes for Version 2.10.2]]}} |- {{Tablerow3|Version 2.10.1|1 Dec 2012|[[Release Notes for Version 2.10.1]]}} |- {{Tablerow3|Version 2.10|16 Nov 2012|[[Release Notes for Version 2.10]]}} |- {{Tablerow3|Version 2.9.1|1 Jun 2012|[[Release Notes for Version 2.9.1]]}} |- {{Tablerow3|Version 2.9|20 May 2012|[[Release Notes for Version 2.9]]}} |- {{Tablerow3|Version 2.8|17 Apr 2012|[[Release Notes for Version 2.8]]}} |- {{Tablerow3|Version 2.7.1|14 Nov 2011|[[Release Notes for Version 2.7.1]]}} |- {{Tablerow3|Version 2.7|30 Sep 2011|[[Release Notes for Version 2.7]]}} |- {{Tablerow3|Version 2.6|14 Jul 2011|[[Release Notes for Version 2.6]]}} |- {{Tablerow3|Version 2.5.5|14 Apr 2011|[[Release Notes for Version 2.5.5]]}} |- {{Tablerow3|Version 2.5.2|1 Mar 2011|[[Release Notes for Version 2.5.2]]}} |- {{Tablerow3|Version 2.5.1|14 Feb 2011|[[Release Notes for Version 2.5.1]]}} |- {{Tablerow3|Version 2.5|12 Feb 2011|[[Release Notes for Version 2.5]]}} |- {{Tablerow3|Version 2.1.2|27 Sep 2010|[[Release Notes for Version 2.1.2]]}} |- {{Tablerow3|Version 2.1.1|20 Sep 2010|[[Release Notes for Version 2.1.1]]}} |- {{Tablerow3|Version 2.1|8 Jul 2010|[[Release Notes for Version 2.1]]}} |- {{Tablerow3|Version 2.0|31 May 2010|[[Release Notes for Version 2.0]]}} |} == Version 1.x == {| {{Table}} {{Tablehead3|Version|Release&nbsp;Date|Release Notes}} |- {{Tablerow3|Version 1.5.9|28 Apr 2009|[[Release Notes for Version 1.5.9]]}} |- {{Tablerow3|Version 1.5.8|4 Apr 2009|[[Release Notes for Version 1.5.8]]}} |- {{Tablerow3|Version 1.5.5|21 Mar 2009|[[Release Notes for Version 1.5.5]]}} |- {{Tablerow3|Version 1.5.2|13 Feb 2009|[[Release Notes for Version 1.5.2]]}} |- {{Tablerow3|Version 1.5.1|8 Feb 2009|[[Release Notes for Version 1.5.1]]}} |- {{Tablerow3|Version 1.5|27 Dec 2008|[[Release Notes for Version 1.5]]}} |- {{Tablerow3|Version 1.4.10|25 Jul 2008|[[Release Notes for Version 1.4.10]]}} |- {{Tablerow3|Build 149|8 Jul 2008|[[Release Notes for Build 149]]}} |- {{Tablerow3|Build 148|13 Mar 2008|[[Release Notes for Build 148]]}} |- {{Tablerow3|Build 147|25 Feb 2008|[[Release Notes for Build 147]]}} |- {{Tablerow3|Build 146|7 Feb 2008|[[Release Notes for Build 146]]}} |- {{Tablerow3|Build 145|27 Nov 2007|[[Release Notes for Build 145]]}} |- {{Tablerow3|Build 144|9 Nov 2007|[[Release Notes for Build 144]]}} |- {{Tablerow3|Build 143|19 Oct 2007|[[Release Notes for Build 143]]}} |- {{Tablerow3|Build 142|9 Oct 2007|[[Release Notes for Build 142]]}} |- {{Tablerow3|Build 141|3 Oct 2007|[[Release Notes for Build 141]]}} |- {{Tablerow3|Build 140|27 Sep 2007|[[Release Notes for Build 140]]}} |- {{Tablerow3|Build 139|21 Aug 2007|[[Release Notes for Build 139]]}} |- {{Tablerow3|Build 138|18 Aug 2007|[[Release Notes for Build 138]]}} |- {{Tablerow3|Build 137|4 Aug 2007|[[Release Notes for Build 137]]}} |- {{Tablerow3|Build 136|22 May 2007|[[Release Notes for Build 136]]}} |- {{Tablerow3|Build 135|12 May 2007|[[Release Notes for Build 135]]}} |- {{Tablerow3|Build 134|14 Apr 2007|[[Release Notes for Build 134]]}} |- {{Tablerow3|Build 133|6 Apr 2007|[[Release Notes for Build 133]]}} |- {{Tablerow3|Build 132|14 Feb 2007|[[Release Notes for Build 132]]}} |- {{Tablerow3|Build 131|20 Nov 2006|[[Release Notes for Build 131]]}} |- {{Tablerow3|Build 130|10 Nov 2006|[[Release Notes for Build 130]]}} |- {{Tablerow3|Build 129|3 Nov 2006|[[Release Notes for Build 129]]}} |- {{Tablerow3|Build 128|1 Oct 2006|[[Release Notes for Build 128]]}} |- {{Tablerow3|Build 127|15 Sep 2006|[[Release Notes for Build 127]]}} |- {{Tablerow3|Build 126|31 Aug 2006|[[Release Notes for Build 126]]}} |- {{Tablerow3|Build 125|30 Jun 2006|[[Release Notes for Build 125]]}} |- {{Tablerow3|Build 124|25 Jun 2006|[[Release Notes for Build 124]]}} |- {{Tablerow3|Build 123|6 Jun 2006|[[Release Notes for Build 123]]}} |- {{Tablerow3|Build 122|24 May 2006|[[Release Notes for Build 122]]}} |- {{Tablerow3|Build 121|24 Apr 2006|[[Release Notes for Build 121]]}} |- {{Tablerow3|Build 120|20 Apr 2006|[[Release Notes for Build 120]]}} |- {{Tablerow3|Build 119|18 Apr 2006|[[Release Notes for Build 119]]}} |- {{Tablerow3|Build 118|28 Mar 2006|[[Release Notes for Build 118]]}} |- {{Tablerow3|Build 117|20 Mar 2006|[[Release Notes for Build 117]]}} |- {{Tablerow3|Build 116|28 Feb 2006|[[Release Notes for Build 116]]}} |- {{Tablerow3|Build 115|12 Jan 2006|[[Release Notes for Build 115]]}} |- {{Tablerow3|Build 114|9 Jan 2006|[[Release Notes for Build 114]]}} |- {{Tablerow3|Build 113|26 Dec 2005|[[Release Notes for Build 113]]}} |- {{Tablerow3|Build 112|19 Oct 2005|[[Release Notes for Build 112]]}} |- {{Tablerow3|Build 111|26 Jul 2005|[[Release Notes for Build 111]]}} |- {{Tablerow3|Build 110|5 Jul 2005|[[Release Notes for Build 110]]}} |- {{Tablerow3|Build 109|23 Jun 2005|[[Release Notes for Build 109]]}} |- {{Tablerow3|Build 108|27 May 2005|[[Release Notes for Build 108]]}} |} == Ancient History == * [[Early C4 Engine Development Worklog]] 37dce1ead5fe7c0dd1831afe36f480504a788a7a Template:Tablerow3 10 9 11 2023-07-15T09:14:49Z Eric Lengyel 1 Created page with "| style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 24px 2px 6px;" | {{{1}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{2}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{3}}}" wikitext text/x-wiki | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 24px 2px 6px;" | {{{1}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{2}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{3}}} dd12aa6e5dab9e652b4b8e7aa0ac6efdf850d305 Template:Tablehead3 10 10 12 2023-07-15T09:15:15Z Eric Lengyel 1 Created page with "| style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 24px 2px 6px;" | {{{1}}} | style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 6px 2px 6px;" | {{{2}}} | style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black;..." wikitext text/x-wiki | style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 24px 2px 6px;" | {{{1}}} | style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 6px 2px 6px;" | {{{2}}} | style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 6px 2px 6px;" | {{{3}}} cc235972bfba2bc0bceecb48c68a8b373fd94e51 Template:Table 10 11 13 2023-07-15T09:16:33Z Eric Lengyel 1 Created page with "style="border: solid 1px #444; border-spacing: 0px; border-collapse: collapse;"" wikitext text/x-wiki style="border: solid 1px #444; border-spacing: 0px; border-collapse: collapse;" 2dabbffafd7012143e71fc2ff64dc805e4acf174 Early C4 Engine Development Worklog 0 12 14 2023-07-15T09:20:20Z Eric Lengyel 1 Created page with "­__NOTOC__ == July 3, 2003 == * Completely redesigned the collision detection architecture. All geometries are now handled uniformly by a general collision detection algorithm. Swept sphere collisions can now occur with arbitrary geometrical shapes. * Removed the restriction that the torus primitive be circular. It can now be elliptical. * Added a flag that forces tangent fields to be calculated numerically for primitive geometries instead of analytically. * Added a ge..." wikitext text/x-wiki ­__NOTOC__ == July 3, 2003 == * Completely redesigned the collision detection architecture. All geometries are now handled uniformly by a general collision detection algorithm. Swept sphere collisions can now occur with arbitrary geometrical shapes. * Removed the restriction that the torus primitive be circular. It can now be elliptical. * Added a flag that forces tangent fields to be calculated numerically for primitive geometries instead of analytically. * Added a geometry space identifier to the <code>GeometryObject</code> class that indicates into what coordinate space its vertices have been transformed. Geometry can exist in world space, object space, or group space. * Implemented portal vertex insertion and removal tools in the World Editor. * Implemented registration mechanisms for controller, property, entity, and effect construction procedures. Templatized the classes encapsulating the construction procedures. * Added a <code>World</code> pointer to the <code>Node</code> class. Every node now knows in what world it exists. * Created subclasses for the World Editor's node info window that are specific to geometries, lights, etc. * Added recognition of spawn location and spectator location markers in the Game Module. * Implemented undo for the Replace Material command in the World Editor. * Added a list of particle systems to the <code>World</code> class so that particle systems now belong to the world in which they exist instead of being stored in a global list by the Particle Manager. * Implemented a diagnostic mode that displays certain collision detection data. * Fixed a very minor glitch in the color picker window. * Wrote a tridiagonal linear system solver that will be used for cubic splines. A discussion of both of these will appear in the 2nd edition of [http://mathfor3dgameprogramming.com/ ''Mathematics for 3D Game Programming & Computer Graphics'']. * Implemented microfacet shading (both isotropic and anisotropic) for metallic surfaces. This code will also appear in the 2nd edition of [http://mathfor3dgameprogramming.com/ ''Mathematics for 3D Game Programming & Computer Graphics'']. == May 22, 2003 == * Created a Math Utilities library and moved various standalone math routines into the <code>Math</code> namespace. * Moved the 256-entry sine and cosine tables from the Particle Manager to the Math Utilities. * Implemented the <code>Manipulator</code> class hierarchy. Manipulators encapsulate all of the object interaction functionality used by the World Editor. Manipulators also contain any extra rendering code used to display non-geometric objects, editor handles, light ranges, etc. This code was previously split between Node subclasses and an <code>EditorData</code> chunk stored within each node. The <code>EditorData</code> structure has now been removed. * <code>Object</code> subclasses have been created for all primitive geometries, portals, and zones. * An generic auxiliary object slot has been added to the <code>InfiniteZone</code> class to accommodate the need for the World Editor to store data somewhere. * Implemented a geometric primitive that represents a rectangular plate with an elliptical hole cut out of it. * Implemented a geometric primitive that represents a right rectangular pyramid. * Removed the texture map resources used to render portals and zones. They are now stored directly in the code (the textures are very simple). * Implemented a mechanism through which an object construction procedure can be registered. This allows different modules to define their own object types and construct them when a world resource is loaded. * The World Editor and Model Importer have been split out into standalone plugin modules. These were the last tools still left in the core engine—all tools now reside in their own modules. * Made some significant changes to the Resource Manager to better accommodate the definition of new resource types in plugin modules. [If the C++ standard had better defined the intended behavior of the <code>export</code> keyword, and compilers actually implemented it, a lot of trouble would have been avoided here.] * Implemented separate panes for geometries, lights, portals/zones, and markers in the World Editor. Also created better icons. * A toggle has been implemented that allows certain geometric primitives to be automatically capped when they are drawn in the World Editor. The box and cylinder geometries receive both a bottom endcap and a top endcap. The pyramid, cone, and dome geometries receive only a bottom endcap. When multiple primitives are created through automatic capping, they are also grouped as required by the shadowing system. * Redesigned the resizing algorithm in the World Editor. Capped geometries can now be resized as a single object. * Implemented automatic multiple selection for groups that contain a geometry with caps. * Added a safety mechanism to the World Editor that will delete empty groups if everything in them is deleted. Of course, the groups come back if the operation is undone. * Implemented portal vertex manipulation in the World Editor. * Created base classes for several of the template utility classes and moved code not dependent on template parameters down so that it doesn't get duplicated. This reduced overall code size by more than 10 percent. * Implemented a mechanism through which manipulators can cache rendering data that remains constant as long as the viewport it's rendering into isn't changing. * Added support for line strip and indexed lines render types in the Graphics Manager. Also added a render state bit for line smoothing. * Completed all light source and sound source tools in the World Editor. * Implemented location marker and cube map marker tools in the World Editor. * Implemented preliminary support for the <code>GL_ARB_vertex_buffer_object</code> extension. * Cancelled plans to support the <code>GL_NV_vertex_array_range</code> extension. == April 11, 2003 == * The sound buffer position notification mechanism in DirectX 9.0a is totally broken. The Sound Manager's dependency on this necessary-for-streaming feature has been removed and replaced by a slightly less elegant timer that fires several times over the span of the main mixing buffer and polls the play position. * Removed upward dependencies from the Input Manager. Hooks are now exposed where the Input Manager needs to call into higher-level code such as the input configuration window. * Made some significant revisions to the new Resource Manager. * Implemented full support for S3TC texture compression. * Implemented optimized support for multiple texture formats in a single texture resource. Only the format that is actually used is loaded into memory. * Texture images loaded from resources are now removed from memory after being transferred to OpenGL. This reduces RAM usage by a ton. The only drawback is that a graphics system restart takes longer now because textures have to be loaded from the disk again. * Added a filter procedure to the <code>FileMgr::BuildFileList()</code> function. * Expanded the <code>ListBox</code> functionality so that it can handle multiple selected items. * Exposed the <code>ListItem</code> class so that it could be subclassed. List items can now draw themselves however they want. * Added a resource catalog for imported resource types. Targa files, text files, and 3DSMax exports now reside in the Import folder. * Redesigned the texture import dialog. It now allows specification of S3TC compression, HILO bump maps, and the recently added texture flags. * The following tools have been split out into Tool Manager plugin modules: ** Sound Player ** Movie Player ** Model Viewer ** Texture Viewer ** Texture Importer ** String Importer ** Font Generator * Added support for HILO textures in the Texture Viewer tool. * Mipmaps can now be viewed in the Texture Viewer tool by hitting Ctrl-M (PC) or Cmd-M (Mac). * Made some performance improvements in the Sound Player tool. * Made several code design improvements in the World Editor. * Fixed a bug in the World Editor's rectangle zoom tool. * Fixed a minor glitch that would cause the extension-enabled flag to be ignored for any extensions that were core features of the currently installed OpenGL implementation (e.g., it would be impossible to turn off texture compression under OpenGL 1.3 or higher). * Fixed a minor bug in the fragment shader code for point light sources (affects ATI hardware only). == March 28, 2003 == * The engine now requires support for the <code>GL_EXT_draw_range_elements</code> extension. (As a core feature of OpenGL 1.2, this extension is supported by all vendors that we care about.) * Added support for the <code>GL_SGIS_generate_mipmap</code> extension. A new texture flag has been defined to indicate that mipmaps should be automatically generated by OpenGL. * Added support for subtractive blending modes using the <code>GL_EXT_blend_subtract</code> extension. * Removed support for the <code>GL_EXT_compiled_vertex_array</code> extension. Superseded by the <code>glDrawRangeElements</code> function and future support for vertex array range functionality. * Removed support for the <code>GL_EXT_secondary_color</code> extension — it's no longer being used. * Whether trilinear filtering is used is now controlled by the <code>textureTrilinear</code> system variable. A new texture flag has been defined to force a texture to used trilinear filtering. * Implemented support for per-pass face culling state. This enables special effect algorithms to render back-facing polygons on one pass and front-facing polygons on another pass. * Created a translucency material attribute. Currently experimenting with the translucency effect. * Changed the Movie Manager functions <code>Activate()</code> and <code>Deactivate()</code> to <code>Initialize()</code> and <code>Terminate()</code> to be consistent with the same functions in the Network Manager. * Made some minor changes to the Movie Manager necessary to support playback of audio files. Any audio file in a format recognized by QuickTime can now be played as a movie. * Added duration and position queries to the <code>Movie</code> class. * Completely rewrote the Resource Manager. ** The location of resources is now determined by the ''catalog'' in which they reside. Catalogs allow related resources to be collected in the same place. A single type of catalog is defined in the Resource Manager that encapsulates a root path leading to a group of resources. Game modules may define additional catalog types that grab resources from arbitrary locations. For example, an application might define a catalog that extracts resources from a pack-file. ** The current resource layout hasn't been changed, but the organization in future builds will take advantage of the packaging capabilities. ** Resource types may now indicate whether resource names include an extension. Movie resource names must now specify the extension used in the file name since different formats are supported. ** Applications may register catalogs with the Resource Manager so that they can be selected when importing various types of data. Import dialogs in future builds will display a target catalog list. * The Graphics Manager now uses conventional vertex arrays with vertex programs. This reduces the overhead of switching in and out of vertex program mode and makes ARB vertex programs easier to read. It also seems to be liked by drivers more. * The MacOS build now requires a G4 processor. == March 19, 2003 == * Changed the internal texture format passed to <code>glTexImage()</code> to force 8 bits per component. ATI drivers were dropping down to something less, causing ugly banding. * Changed binding to vertex attribute arrays in ARB vertex programs to be conformant with the spec. * Added more robust error reporting to the vertex/fragment program loading code. * Fixed an overflow problem that showed up when using <code>GL_ATI_fragment_shader</code> to perform environment-mapped bump mapping. == March 7, 2003 == * Added support for rectangle textures using the <code>GL_NV_texture_rectangle</code> extension. Rectangle textures are not restricted to power-of-two sizes, but cannot have mipmaps and cannot use repeating wrap modes. * Added support for the <code>GL_ATI_separate_stencil</code> extension. This enables an optimization on ATI hardware that is equivalent to the functionality provided by the <code>GL_EXT_stencil_two_side</code> extension. Both allow stencil shadow volumes to be rendered in a single pass by using separate stencil operations for front-facing and back-facing polygons. * Added occlusion query functionality to the Graphics Manager and the World Manager using the <code>GL_NV_occlusion_query</code> extension. An occlusion query can now be performed during the ambient rendering pass, and its result can be used after the lighting passes to render special effects. * Added support for the <code>GL_NV_point_sprite</code> extension. Particle systems may now specify the <code>particlePointSprite</code> flag indicating that its particles should be rendered as point sprites, if available. This allows a 75% reduction in vertex processing for some particle systems. * Added support for anisotropic texture filtering using the <code>GL_EXT_texture_filter_anisotropic</code> extension. The maximum anisotropy used during filtering is controlled by the <code>textureAnisotropy</code> system variable. A value of 1 corresponds to no anisotropic filtering. * Updated texture format and added support for compressed texture images. Changed texture resource extension to <code>.tex</code>. * Developed a Tool Manager class and implemented a tool plugin architecture. The texture viewer utility has now been split out into a plugin, and other built-in tools will follow. == March 27, 2002 == * The game module is now present in the executable download. Spectator camera controls have now been moved there, and it is now possible to insert a player into the world. Issuing the "spawn" command in the command console will put the player in the world, and issuing the "spectate" command will take him out. * The game play menus have not yet been added, but certain setup dialogs can be accessed through the command console. Type "display" to bring up the Display Setup dialog, and type "input" to bring up the Setup Controls dialog. * The player can fire the plasma gun at this time. No other weapons are implemented yet. * No collision detection is implemented at this time, so the player can run through anything, and the plasma bursts will never hit anything either. * This build still uses a single hard-wired light source. Build 14 will use the actual light sources placed in the world with the world editor. * Shadow-casting set determination will not be implemented until build 14, so objects that are not visible themselves will not cast a shadow. If you see shadows blinking out, that's why. * The shadow faceting sometimes visible on the character is a known issue with the stencil shadow design. Ways to eliminate this artifact will be explored in the future. * The executables and data are now separate downloads. They just need to be unzipped into the same directory. * This fixes all previously know world editor bugs. * Grouping has been implemented in the world editor. There currently is no visual indication that a group exists (there will be), and ungrouping is not yet implemented (grouping can be undone, however). Grouping is necessary for two things: 1) level of detail synchronization, and 2) connected shadow volume consistency (this allows a really nice optimization). * It is now REQUIRED that objects sharing edges belong to the same group. For instance, if you create a cylinder and two endcaps, you must select all three objects and then group them. I'm thinking that in the future objects will be created as a group with their endcaps already present, but this will not be implemented for a few more builds. * The world format in this build is not backwards compatible. * The world editor will now pick selected objects before unselected objects when you click in a viewport. In some cases, this may prevent you from selecting an object for which another (already selected) object covers the same space in the viewport. Just deselect the other object first. == January 26, 2002 == * Added auto-panning to the world editor so that viewports will pan when the cursor goes out-of-bounds while drawing, moving, rotating, or resizing. * Implemented the multiple undo architecture for the level editor. * Implemented selection picking in the world editor. * Implemented the move and rotate tools in the world editor. * Added constraints to the move and rotate tools so that holding down shift only allows an object to be moved horizontally or vertically or rotated in increments of 45 degrees. * Added handles to the world editor. Objects can only be rotated or resized by grabbing handles -- they also determine the center of rotation and constraints on what dimensions of an object get resized. * Implemented the pulldown menus for the world editor. * Added checkmarks and command keys to the <code>MenuItem</code> class. * Added load and save functionality to the world editor. The same functionality is used to load worlds for actual gameplay. * Added a name box to the file picker for saving files. * Implemented the undo mechanism for resizing objects in the world editor. == January 12, 2002 == * Redesigned the entire shading system. The graphics manager is quickly moving towards a real-time global lighting and shadowing engine. * Wrote the ambient shader setup code. This handles anything that does not involve an actual light source, including ambient illumination, emission, and environmental reflections. Environment-mapped bump mapping also happens here. * Added ambient light transition zones to the ambient shader. This allows objects straddling the boundary between two zones to have a gradually changing ambient light color. * Implemented an algorithm that clips an arbitrary convex polyhedron against a plane. The algorithm maintains edge connectivity and face adjacency information. * Implemented a new polygon triangulation algorithm that handles polygons having three or more collinear vertices. This arises during T-junction elimination. This algorithm will appear in the article "T-Junction Elimination and Retriangulation", in [http://gameenginegems.com/gemsdb/book.php?id=5 ''Game Programming Gems 3''] to be published in July, 2002. * Wrote an extension to the polygon triangulation algorithm so that it can handle concave polygons and arbitrary planar regions having nonzero genus. * Updated the particle system code and improved the way that line particles are rendered. * Implemented a new node enumeration mechanism that iterates through all of the subnodes having particular type of a given root node. * Updated the surface marking code to use the new node enumeration code. * Implemented a transform and bounding volume invalidation mechanism for the global node tree. * Removed support for the <code>WGL_3DFX_gamma_control</code> extension. * Improved the texture hashing scheme so that it is more robust and treats texture resources and procedurally-generated textures the same way. * Rewrote the Resource Manager. It is now more general and resource locations can be customized to support things like packfiles. * Designed a general vertex program for rendering volumetric fog. * Implemented the infinite light shader setup code. * Designed a system for allocating and calculating vertex attribute arrays on the CPU for machines that don't have a GPU with programmable vertex shader capabilities. * Began writing the C4 World Editor. * Implemented orthographic and perspective viewports for the world editor. * Implemented gridline rendering in the world editor. * Implemented viewport pan and zoom tools in the world editor. * Implemented viewport configuration controls in the world editor. * Implemented geometry drawing tools in the world editor. * Added a snap-to-grid toggle for geometry drawing in the world editor. * Added a draw-from-center toggle for geometry drawing in the world editor. * Improved the window centering code for the internal interface system. * Designed a new texture map format that allows multiple image formats to exist in the same resource. The format chosen at run time depends on the graphics hardware capabilities. * Updated the skybox rendering code. == August 4, 2001 == * Wrote the Movie Manager. A QuickTime Movie can now be played into any window or any texture map. The Movie Manager can also be used to stream audio tracks in any format that QuickTime supports. * Enhanced the texture map resource format so that multiple images can be stored in a single texture. This is good for things like cube texture maps, which require six images. * Added flags to the Ray structure which can be used to control what kinds of objects the ray can intersect. This is useful for ignoring objects which do not cast shadows or should not appear in an environment map. * Added support for the <code>GL_EXT_abgr</code>, <code>GL_EXT_bgra</code> and <code>GL_EXT_packed_pixels</code> extensions. * Upgraded the Input Manager under Windows to use DirectInput 8. * Improved the way that the Input Manager handles being switched into the background. == July 28, 2001 == * Made dozens of small enhancements and fixes that accumulated into a long list while I was working on the book. * Changed usage of MacOS <code>FSSpec</code> records to the recommended method. * Added diagnostic tools which allow normal and tangent vectors to be seen in real-time. * Implemented a direct reflection color for environment mapping. * Improved bump map construction code. * Changed default shader blend mode to replace. * Added the EAX environment size field to the Sound Manager. == July 18, 2001 == * Finished writing the book [http://mathfor3dgameprogramming.com/ ''Mathematics for 3D Game Programming & Computer Graphics''], to be published by Charles River Media in December. * Implemented the Cook-Torrance BRDF physically-based lighting model in the shader system. This enables accurate isotropic and anisotropic reflections based on surface roughness and specular properties. A detailed analysis of this lighting model is presented in Chapter 6 of my book. * Rewrote the fluid surface simulation code. It is now very clean and based entirely on the 2D wave equation with viscous damping. The new model now correctly takes wave speed and viscosity into account. The entire final chapter of my book provides a thorough discussion of the technique that is now used in the engine. * Added support for different types of ADPCM wave files that are floating around out there. * Added hooks to the Resource Manager that allow custom resource loading routines to be installed. == March 24, 2001 == * Finished implementing complete support for the following lighting equation on Nvidia GeForce and ATI Radeon hardware. color = [D * T * (N · L) + S * G * (N · H)4] * X + A * T + E * M D = diffuse reflection color * primary light color S = specular reflection color * primary light color A = diffuse reflection color * ambient light color E = emission color T = primary texture color G = gloss map color X = shadow map color M = emission map color N = bump map normal vector L = vertex space direction to light H = vertex space halfway vector * Components of the above equation can be used in any combination. The G term can be a separate texture map or it can be stored in the alpha channel of another texture. The N · H term can be replaced by an environment map to achieve true environment-mapped bump mapping (GeForce 3 only). The shader system renders objects using per-pixel lighting with as few passes as possible. Almost everything can be done in a single pass on GeForce 3 hardware. Vertex programs are used where appropriate to perform vertex space basis calculations and texture shader setup. * Designed a new architecture for assigning texture mapping coordinates to world structures. Textures are now transformed in 2D texture space and then wrapped onto a structure using a structure-specific function. This method also makes vertex space basis calculations very easy. * Added support for emission maps in the 3DSMax geometry export plugin and in the model import dialog. == March 17, 2001 == * Added code which stores complex register combiner settings in OpenGL display lists. * Implemented complete support for emission maps. * Added the ability for a normal map to contain an alpha channel gloss map. * Redesigned the shader initialization code for per-pixel lighting. Shaders now assemble themselves out of much simpler components. * Implemented environment-mapped bump mapping using the <code>GL_NV_texture_shader</code> extension. * Moved the <code>SmokeTrail</code> particle system code to the Game Module. * Implemented support for the <code>GL_NV_mac_get_proc_address</code> extension. == March 10, 2001 == * Implemented a complete pulldown menu system. * Moved all of the title window functionality into pulldown menus. * Added a Tools menu which provides access to utility windows and import functionality. * Added an <code>ImportMgr</code> class and separated all of the actual import code from the user interface code for the import windows. * Made various improvements to the Window Manager and dialog element classes. * Implemented support for anisotropic texture filtering using the <code>GL_EXT_anisotropic_texture_filter</code> extension. * Added a color array to the surface marking class so that marking edges will fade based on their vertex normals. This eliminates the hard edges that could previously appear on highly curved surfaces. == March 3, 2001 == * Upgraded the 3DSMax geometry plugin so that it exports gloss map and bump map information. * Added vertex space basis calculations to the model importer and to the real-time mesh deformation code. * Added the ability for the alpha channel of a texture map to be used as a gloss map. * Added a sort function to the <code>ListBox</code> interface element. * Made massive improvements to the model import dialogs. Users can now deactivate parts of an exported geometry, change diffuse, emission, and specular colors, and select texture maps, bump maps, and gloss maps for each part. == February 24, 2001 == * Made several improvements to the terrain code. Terrain collision detection and shadow generation are now more accurate. * Improved the code which blends the seams between neighboring lightmaps. * Updated the model format and model import code so that it possesses the same general attribute array and texture map capabilities that world structures now support. * Moved all edge finding code for shadows into the model import code so that those calculations are no longer necessary when a shadow is added to a model. * Implemented multiple levels of detail for shadow volumes. Previously, the shadow always corresponded to a model's lowest level of detail. == January 27, 2001 == * Improved the transparent object distance sorting algorithm. * Changed the way that light map saturation is handled so that color hues are not altered. * Added a format field to texture maps. * Added a user-configurable desktop color to the Window Manager. * Implemented stream classes for loading and saving resource data. This encapsulates information such as endianness, making load/save code simpler. * Added a flag to the <code>LightSource</code> class in the Ray Tracer which inhibits the light source's participation in light map generation. This is useful for placing a single light in the world that is used for real-time illumination in place of several other lights which may exist for higher-detail lightmaps. == January 20, 2001 == * Changed the rendering order of shadow volumes so that they are rendered before the object to which they are attached. * Reduced the amount of data written to a world resource for invisible geometries. * Removed the intermediary classes <code>PlanarStructure</code> and <code>CylindricalStructure</code> and moved their specialized visibility tests into the base <code>Structure</code> class. * Added spherical and cylindrical geometry placeholders for special effects. This allows the visibility of certain effects to be determined using the global zone/portal and BSP tree algorithms. * Added a rising smoke effect to the Game Module which is attached to torches. * Implemented a new sorting algorithm for transparent objects. The new system allows transparent objects to be attached to other transparent objects so that they're rendered consecutively. This is nice for things like scorch marks on transparent surfaces. * Added a two-sided flag to the 3DSMax geometry export plugin so that parts of a model may have backfaces rendered in the engine. * Improved the way that input elements are deactivated when the input mode is changed; for example, when switching from game controls to user interface input. == January 13, 2001 == * Added a texgen light map flag to the <code>Geometry</code> class which will suppress the generation of light map coordinates for geometries that generate them at run time (e.g., the fluid geometry). * Improved light map sample coordinate generation for primitives whose geometry doesn't cover the entire area that its light map covers. This eliminates many edge darkening artifacts on some of the curved surfaces. * Restructured the layout of zone and environment classes so that they use the same code to define the volumes of space that they affect. * Added sphere and cylinder volume types which can be used as zones or environments. * Added clipping planes to the zone and environment volumes so that they can be carved into more flexible shapes. * Added file name type-out matching to the file picker dialog box. * Added an auto-scroll option to the <code>ListBox</code> dialog element that will display the current selection when it is changed. * Added default text and window colors to the Window Manager which can be changed by the user. == January 6, 2001 == * Added code that handles cases in which static light map sampling points fall outside a geometry's clipping planes. Projecting the sampling point onto the plane eliminates darkening artifacts that can occur in corners where mutually clipped geometries meet. * Added a natural plane function to all of the geometry classes in the Ray Tracer. These are useful for clipping adjacent geometries to the planes formed naturally by a primitive (such as the end planes of a cylinder). * Added a flag which indicates whether the sky box should be rendered when a certain zone is rendered. Previously, the sky box was only rendered when the topmost zone in the hierarchy was visible. * Implemented the vertex lighting option for world geometry as an alternative to static light mapping. This really helps load time and rendering performance in outdoor environments where there may be hundreds of trees which don't really need light maps for anything other than their trunks. * Finalized the Ray Tracer intersection code for the terrain geometry. == December 23, 2000 == * Made several general enhancements to the terrain collision detection code. * Began implementing the Ray Tracer intersection code for terrain geometry. * Added the Information component class to the Ray Tracer. This is used to store general types of data which is shared among more than one component in a scene. * Added the ability to create multiple terrain geometry objects which draw from the same height field data. This is useful for dividing a large outdoor area into smaller blocks which may reside in different zones. It also improves dynamic lighting performance considerably. * Implemented a light map expansion technique which helps eliminate discontinuities visible in the light maps of adjacent geometries. * Added an origin point to the <code>BoxZone</code> class so that nodes containing such a zone don't need to have a translation. * Added code to the World Builder which compares multiple bounding spheres for a structure (calculated through different methods) and selects the best one. == December 16, 2000 == * Simplified most of the conventional lighting code in the main rendering pipeline. * Upgraded the quality of light map generation for terrain geometry. * Implemented the collision detection algorithm for terrain geometry. * Added simple collision detection to chase cameras so that they won't go through walls. * Added a mechanism to the character collision code which makes uphill motion appear much smoother. * Modified the Macintosh versions of the Sound Manager and Network Manager so that they are able to run in the Carbon environment. == December 9, 2000 == * Added bump mapping flags to the <code>Shader</code> class which control certain lighting variables and specify optimization hints. * Implemented bump mapping for point and spot light sources. * Wrote vertex programs for bump mapping with point and spot light source attenuation. * Implemented a mechanism for invalidating vertex space light direction and halfway vectors for bump-mapped objects which do not have the <code>bumpDynamic</code> flag set. * Wrote a vertex program component assembler for generating vertex programs at run time. This replaces the combinatorial explosion of canned programs that was starting to materialize. Small pieces of vertex program code are now stored in the executable and put together at run time to create a complete program that fits a shader's needs. * Removed the <code>VertexProgramResource</code> resource type. * Consolidated infinite, point, and spot light types into a single light class. * Extended the <code>Environment</code> class so that it describes a lighting model for a region of the world in addition to the acoustic properties that it previously maintained. Ambient light settings and all static light sources now belong to environments. == December 2, 2000 == * Implemented the convention of texture map slots in the shader system. Instead of just having a list of texture maps, each renderable object now possesses a table of texture maps whose entries may be zero. Particular indexes within the table have semantic meaning such as ordinary texture map, light map, normal map, and gloss map. * Implemented register combiner state settings for all 21 possible types of rendering passes for per-pixel bump mapping. The pass(es) chosen for an object depend on the number of available texture units, number of available general combiner stages, and whether the object is to be rendered with a texture map, specularity, gloss map, and/or shadow map. * Implemented vertex programs for each of the 21 bump mapping passes which calculate vertex space light direction and halfway vectors. * Added support for per-stage constant color inputs for register combiners. * Added a scroll size to the <code>ScrollBar</code> class which lets you specify how far to scroll when the user clicks the up or down arrows. == November 18, 2000 == * Added separate conventional array state and vertex attribute array state flags to the Graphics Manager. * Added specialized shader structures for several different lighting configurations. * Added a control panel that allows you to enable/disable any OpenGL extensions. This works without having to restart the engine. * Implemented more versatile support for conventional OpenGL lighting. The engine now supports diffuse, specular, and emission material colors for every renderable object. * Added support for multiple light maps in the World Builder. This is needed to provide different light maps which are used depending on what hardware features are available. For instance, the N · L term should not be included in the light map when performing per-pixel bump mapping. * Expanded the world and model resources so that objects can have an arbitrarily number of textures applied to them. Each texture also carries a type such as light map or bump map. == November 11, 2000 == * Added a blending mode for modulating by the contents of the destination alpha channel. This is used for the smooth self-shadowing term during the specular pass for per-pixel bump mapping. * Added a scale factor to the normal map generator allowing one to control how pronounced the bumps in a normal map are. * Implemented bump mapping for the ATI Radeon using the <code>GL_EXT_texture_env_dot3</code> extension and three texture units. * Implemented NV20 vertex programs for vertex space light direction and halfway vector calculations. * Began writing a book tentatively entitled [http://mathfor3dgameprogramming.com/ ''Mathematics for 3D Game Programming and Computer Graphics''] which will be published by Charles River Media (the same company who published [http://gameenginegems.com/gemsdb/book.php?id=3 ''Game Programming Gems'']). == November 4, 2000 == * Overhauled the way in which attributes are applied in the Ray Tracer. Each of a geometry's attributes now modify the surface shading state in a single function. * Rearranged and simplified parts of the Ray Tracer which work with attributes. * Rewrote most of the real-time shader architecture. Shaders can now hold multiple textures, they have their own set of vertex attribute arrays, and they can be invoked for multiple passes. The first time that a particular shader is used, it calculates the number of passes that it needs and which textures should be used on each pass. This removes some computation from the old rendering pipeline and turns it into precomputed data. * Moved the remaining light setup code out of the main rendering execution pipeline. This is now completely precomputed on a per-view basis. * Moved the wireframe rendering pass to a separate subroutine. * Implemented support for the <code>GL_EXT_texture_env_combine</code> and <code>GL_EXT_texture_env_dot3</code> extensions. == October 28, 2000 == * Finished client-to-server multiplayer communications code. * Added a <code>SpectatorCamera</code> class to the Game Module. * Refined the wave propagation code for fluid surfaces. * Added normal map generation to the texture importer (this is used to import bump maps). * Added a component count to the texture coordinate array in the <code>Shader</code> class so that 3D coordinates could be specified. This will be used for 3D textures as well as vector arrays for per-pixel lighting effects. * Implemented shaders for per-pixel bump mapping. Full bump mapping is done in two parts: a diffuse reflection pass and a specular reflection pass. * Added a tangent vector to the Ray Tracer's hit data structure so that a local tangent space coordinate system could be derived from a ray intersection. * Added the <code>BumpMapAttribute</code> class to the Ray Tracer and implemented normal vector perturbation. == October 21, 2000 == * Implemented a general property list architecture allows arbitrary data to be associated with any structure in the world. * Ripped out the old material data structures and replaced them with properties. * Added a default property list to the World Manager. If a structure does not have a property of a certain type, then the default property can be used instead. * Added an overridable collision function to the <code>Character</code> class similar to the function which already exists for the <code>Projectile</code> class. This allows the Game Module to implement a custom response whenever a character collides with a structure. * Added a teleport destination property to the Game Module. This property is attached to structures which teleport characters when they collide with it. * Finished moving all world building functionality to World Editor window. * Implemented full support for the <code>GL_NV_vertex_program</code> extension. * Implemented preliminary support for some yet-to-be-disclosed Nvidia extensions. == October 14, 2000 == * Implemented general plane clipping in the World Builder. Any geometry can now be clipped by an arbitrary number of planes, and the new vertices are automatically fused to adjacent structures in the world. * Implemented a calculation which determines how large a light map should be for a geometry after it is clipped. * Added a general normal vector and winding reversal subroutine to the World Builder which operates on any of the possible render types (such as triangle fans or quad strips). * Added a light map flags field to the <code>Geometry</code> class. * Modified the <code>TextureMapAttribute</code> class so that it can still be used even if the texture map that it references is not available. * Implemented several generic texture mapping topologies. Geometries can now be auto-mapped using planar, radial, cylindrical, polar, or toric mappings. * Changed the primitive type for the revolved cubic spline geometry from indexed triangles to indexed quads. * Made some of the interactions between the World Builder and each geometry class a little cleaner. * Implemented preliminary support for the <code>GL_NV_vertex_array_range</code> and <code>GL_NV_fence</code> extensions. == October 7, 2000 == * Added a generalized global variable system to the engine core. This system manages persistent variables which can be created at any time by the engine or by the Game Module. These variables are written to a config file, and they can be edited by the user in the command console. * Removed the old Preferences Manager and replaced it with global variables and a config file which is executed at startup. * Generalized the input element binding functionality so that any element can be bound to an action or to a series of commands. * Implemented a generic file selection dialog. * Implemented a general pixel map blitting function (along with an Altivec accelerated version). * Implemented a new layout for the Host Game dialog in the Game Module which now includes a picture of the selected world. * Improved collision detection efficiency a little bit. * Added full support for elliptical geometry to the Ray Tracer and the World Manager. * Removed all half- and quarter-geometry primitives in favor of absorbing them into the general clipping plane architecture. Efficiency is reduced slightly, but it makes a negligible difference at run time -- the savings in less code duplication and a simpler geometry hierarchy more than pays for it. == September 30, 2000 == * Implemented automatic global vertex fusion. This ensures that coincident vertices belonging to adjacent structures actually have the same exact global coordinates, which is the first step in preventing seams. * Implemented automatic global T-junction elimination. Whenever a vertex belonging to one structure falls on an edge of an adjacent structure, a new vertex is added to the adjacent structure at the exact same coordinates. This makes every world absolutely free of seams. * Made surface markings more memory efficient by implementing a multiple-size vertex array. * Added a flag to the Model class which suppresses rendering of the model through the normal world view. This is useful for rendering the local player model in an FPS since the model shouldn't be rendered from the player's perspective, but should still appear in mirrors and portals. * Added a collision padding parameter to the Zone class so that structures that stick out of the zone a little bit are still considered for collision detection within a certain distance of the zone boundary. * Added the ability for any geometry in the World Builder to link to another detail group which doesn't contain it. This allows a level designer to indicate that the geometry should change detail level at the same time as the group. * Added an altitude angle to the <code>LocationMarker</code> class. * Added a minimum alpha setting to the <code>TunnelMarker</code> class. * Added collision detection to the spectator camera in the Game Module. * Added a location type to the Game Module which indicates where the spectator camera should be placed when a world is loaded. * Implemented window minimization functionality in the Window Manager. * Implemented a texture viewer window. * Made massive changes to the Resource Manager. Everything has now been changed from number based to name based. * Removed the <code>CursorType</code> type -- cursors are now identified by their texture map name. * Removed constants for selecting fonts -- fonts are now identified by their resource name. * Added an extended version of the <code>FileMgr::BuildFileSpecList()</code> function which builds a list of files whose names begin with a given string. * Moved the animation import functionality to the Model Viewer window. Animations for a specific model are now identified by names which start with the model's name. == September 23, 2000 == * Implemented a geometry class for soft light cones around spot lights. * Added a parameter to the <code>Geometry</code> class which controls the minimum number of subdivisions that a curved surface must always have. * Added a flag to the Geometry class which allows certain structures to live in their own object space instead of global space. * Implemented the <code>EmissionAttribute</code> class in the Ray Tracer. This attribute provides a way for a surface to appear to give off light. * Implemented invisible geometries, which exist for the purposes of collision detection, but don't render anything. * Added collision flags to every structure in the world so that geometry may be penetrable to some types of objects but solid to others. * Added specialized visibility test functions to the <code>Structure</code> classes to achieve more efficient culling. * Improved the collision detection algorithm for torus-based structures and revolved cubic spline structures. * Added a post-processing function to the light map generation code in the World Builder. * Added an application-definable type field to location markers. * Added a callback function to tunnel markers so that applications can modify a tunnel's transform during gameplay to get floating effects, etc. * Moved all rendering options from the Graphics Manager to the World Manager. * Added more rendering options to the Display Settings dialog. * Added code to disable Alt-Tab and the Start menu on Windows systems. == September 16, 2000 == * Implemented a better solution to the degeneracy problems that can arise during portal clipping. * Implemented the <code>Torus</code> geometry class in the Ray Tracer and the World Builder. * Added support for dark lights (lights which subtract color from the surfaces that they illuminate) in the Ray Tracer. * Added primitive geometry classes to the Ray Tracer corresponding to the first quadrant of each of the circular geometries. Using these is a bit more efficient than chopping down a larger primitive with a clipping plane. * Added an optional tangent array to all geometry classes which can be used when a single tangent vector does not provide enough information to calculate tangent planes at every vertex. This was necessary to correctly apply dynamic lights to geometries such as domes and tori. * Implemented line particles and added a flag to the <code>ParticleSystem</code> class which causes particles to render as a line connecting their current positions to their previous positions. * Implemented preliminary support for the <code>GL_NV_vertex_program</code> extension. == September 9, 2000 == * Implemented analytical root solvers for arbitrary cubic and quartic polynomials. * Implemented a general revolved cubic spline geometry class. This allows a level designer to specify a set of points which represent the radius of a cylindrically symmetrical object at various heights above the object's base. The World Builder calculates a smooth cubic spline connecting the given points and revolves the spline about the local z-axis. Ray intersection calculations involving this geometry class are mathematically precise. The object isn't just surrounded by a bounding cylinder for collision detection -- the points of intersection of a line with the actual cubic surface are determined allowing accurate interaction with other objects. * Added adaptive subdivision to the revolved cubic spline geometry. This puts the vertical subdivisions where they need to be (where the curvature is the greatest) in order to give the object the best possible appearance. * Upgraded the input configuration window so that it uses the recently implemented hierarchical interface context architecture. * Tweaked the Game Module code which controls the conditions under which a grenade comes to a rest. == September 2, 2000 == * Implemented sky boxes -- boxes with up to six sides which move with the camera and contain a distant background image. When rendering a scene, the World Manager keeps track of which portions of the skybox can be seen through portals leading to the outside world and then renders only those parts which are visible. * Added sky box parameters to the World Builder, including rotation parameters for creating outer space effects. * Added sky box support to the Ray Tracer so that environment maps pick up the sky box texture maps instead of just the background color when a ray doesn't hit anything. * Added the ability to specify color arrays for <code>Renderable</code> objects using 4-byte colors in addition to 4-float colors. * Improved the appearance of dynamic lights when they are very close to curved surfaces. * Implemented automatic mirror detection in the <code>TunnelView</code> class and added a winding direction state to the Graphics Manager which is flipped when rendering through a mirror. * Tweaked several special effects so that they render symmetrically through mirrors. * Implemented automatic texture coordinate alignment in the World Editor. * Added a rocket exhaust glow effect to the Game Module. == August 26, 2000 == * Implemented a subfrustum projection matrix calculation for the <code>TunnelView</code> class which enables optimal use of hardware clipping for remotely rendered scenes through portals and mirrors. * Added fading parameters to the <code>TunnelMarker</code> class so that the transparency of the structure covering the tunnel can be adjusted based on the camera's distance from the tunnel. * Finished all optimizations for portal and tunnel rendering. The engine now performs very optimal geometry visibility culling through portals. * Added a portal count to the graphics stats window. * Added a function to the World Manager which enumerates all structures which intersect a given sphere. This is now used to determine what structures are illuminated by dynamic lights and what structures to which surface markings need to be applied. * Implemented a primitive geometry class in the Ray Tracer for an inverted disk (a plate with a hole cut out of it). * Added primitive geometry classes to the Ray Tracer corresponding to the positive halves of each of the circular geometries. == August 19, 2000 == * Ripped out the enhanced BSP tree code. It wasn't working out as well as I had hoped. * Implemented a generalized <code>View</code> class (and specialized subclasses) which represent the viewer. These will allow easier implementation of remote scene rendering (e.g., areas visible through teleporters or viewscreens). These also make the architecture for switching between the World Manager views, the Window Manager views, and any <code>Viewport</code> interface elements a lot cleaner. * Implemented a remote rendering architecture which allows a scene to be rendered from multiple perspectives. This is used to produce effects such as video screens, mirrors, and teleporters through which the player can see distance regions of the world. * Added the <code>TunnelMarker</code> class to the World Editor which specifies the location, shape, and target region for a remote rendering portal. * Added the <code>SoundMarker</code> class to the World Editor which indicates that a sound should emanate from a specific location in the World. * Added a list of sound sources to the Volume class. Sound sources belong to the smallest volume which contains their audible ranges. * Added more precise distance functions to each structure so that dynamic lights would illuminate fewer objects that were outside their ranges. * Added a focal length setting (which controls the field of view) to the World Manager. == August 12, 2000 == * Implemented an entirely new architecture for large-scale geometry management, collision detection, and visibility determination. Worlds are now organized into a hierarchical tree of disjoint zones, each of which has its own BSP tree storing the geometry contained in the zone. When rendering, the World Manager determines inside which zone the camera lies and renders that zone's BSP tree first. * Implemented a portal architecture which connects zones to other zones at the same level in the tree or to enclosing zones. After the BSP tree for the zone containing the camera is rendered, the World Manager scans through the list of portals for that zone. If a portal is visible, then the zone to which that portal connects is rendered in a recursive manner, but restricted to the view volume determined by the camera position and the vertices of the portal. (Thus, all world geometry rendered during a single frame must be connected to the zone containing the camera through a path of visible portals.) * Enhanced the BSP tree design so that structures which intersect another structure's splitting plane are no longer referenced by both the positive and negative subspaces. Instead, the set of structures which intersect the splitting plane for a particular BSP tree node are further organized into another mini-BSP tree using a splitting plane perpendicular to the original splitting plane. This can happen a third time using the splitting plane perpendicular to the first two, but any geometry remaining after that (which must intersect the structure which originally split it) is just crammed onto the same BSP node. * Implemented the following Zone subclasses: <code>InfiniteZone</code>, <code>PolyhedronZone</code>, <code>CylinderZone</code>, <code>SphereZone</code>, and <code>BoxZone</code>. * Generalized the sphere-frustum and cylinder-frustum intersection tests to work with the arbitrary polyhedral view volumes created by portals. * Upgraded the obstruction, collision, and sound occlusion detection code to operate on the new zone hierarchy and BSP tree format. * Removed the BSP tree for environmental volumes and replaced it with a hierarchical volume tree. * Added an <code>InfiniteVolume</code> class to act as the top level volume in the environmental volume tree. * Added geometry flags for indicating whether structures can receive surface markings or dynamic lighting. == August 5, 2000 == * Improved the surface marking triangle generation algorithm. It now creates an optimal set of triangles corresponding to the intersection of a surface with the marking boundaries. * Implemented a generalized shader architecture. Multiple texture layers and special effects on all renderable objects are now represented by a series of <code>Shader</code> classes. * Implemented high-quality dynamic light sources using the new shader architecture. * Improved the method by which lists of renderable objects are sorted. It is now possible to specify for each renderable object which shader (and thus which texture map) to sort by. * Added an optimization to the <code>ChainStructure</code> rendering code. * Added the rocket launcher code and the <code>Rocket</code> projectile class to the Game Module. * Added dynamic lighting effects to the Game Module. == July 29, 2000 == * Created a special <code>ChainGeometry</code> class which, during a world build, organizes a group of appropriately positioned transparent geometries into a one-sided BSP tree, or "chain". During gameplay, the corresponding <code>ChainStructure</code> class is then able to render all of the transparent faces in back-to-front order. This will be used primarily to render plantlife, whose texture maps generally contain a lot of transparent regions. * Rewrote most of the Display Manager. The DirectDraw code has been replaced by the equivalent Win32 function calls, the MacOS DrawSprocket code has been simplified, and the gamma loading subroutine can now be overridden (allowing the OpenGL context to install its own gamma loader). * Added support for the <code>WGL_3DFX_gamma_control</code> extension. * Implemented display fading functionality for the Windows build (it's been Mac-only for a while). * Added the <code>Global</code> base class template which provides a more elegant way to clean up a global pointer to an object when an exception is thrown from its constructor. * Added the <code>ObjectWrapper</code>, <code>SharedWrapper</code>, and <code>ArrayWrapper</code> classes to encapsulate safe pointers to normal objects, reference counted objects, and arrays, respectively. == July 22, 2000 == * Gave the Window Manager a major overhaul. The <code>Window</code> class and <code>InterfaceElement</code> class are now derived from a new <code>InterfaceContext</code> class, which is itself derived from the <code>DrawContext</code> class. * Implemented a hierarchical interface element architecture. Every interface element now exists in its own local coordinate space. This will allow for easy implementation of scrolling control panels in the World Editor. * Added the <code>ColorBox</code> interface element and the associated <code>ColorPicker</code> dialog box to serve as a standard interface for choosing RGBA colors in the World Editor. * Added the ability to insert division lines into the <code>PopupMenu</code> interface element. * Added the Build Settings panel to the World Editor. * Added a clip rectangle stack to the <code>DrawContext</code> class. * Implemented 2D clipping in text renderer. * Added underwater behavior for the grenades in the game module. * Implemented support for the <code>GL_NV_fog_distance</code> extension. == July 15, 2000 == * Designed <code>Link</code> and <code>LinkTarget</code> classes to provide a leak-proof general mechanism for cross linking between different objects. * Added boundary and interior points to the water ripple effect. Water geometry can now be carved into any arbitrary shape. * Improved light map and environment map generation in the Ray Tracer. * Started implementing the terrain classes in the Ray Tracer and the World Manager. * Fixed a collision detection problem for characters when running into surfaces forming an acute angle with the ground. * Implemented auto-scrolling for the <code>PopupMenu</code> interface element. * Finally decided that it was necessary to add general 2D draw contexts to the Window Manager. Added the <code>DrawContext</code> class which encapsulates a pixel map, a current color, a current pattern, and a clipping rectangle. It also has a movable origin. * Implemented clipping for all 2D drawing primitives. Everything is now clipped to the draw context bounds and the current clipping rectangle. == July 8, 2000 == * Moved the water and fire effects into their own Structure classes and added corresponding geometry classes to the Ray Tracer and World Builder. * Implemented per-vertex light map displacement for liquid surfaces. This allows shadows to be mapped onto the waves in the correct manner. * Added water collision reactions to the game module. Lobbing a grenade into the water now creates waves emanating from the point of impact. * Added generalized support for texture coordinate generation. TexGen modes currently supported are object linear, sphere map, normal vector, and reflection vector. * Implemented support for the <code>GL_EXT_secondary_color</code> extension. * Implemented support for the <code>GL_NV_register_combiners</code> extension. * Rewrote the multipass/multitexture management portion of the main <code>Renderable</code> execution pipeline so that it could handle arbitrary register combinations. * Implemented per-pixel light map modulated specular highlight (phong) shading and applied it to the water effect. * Added the <code>ReflectionAttribute</code> class to the Ray Tracer. * Added the <code>CubeMapMarker</code> class to the Ray Tracer and World Builder. This object is used to mark locations where cube environment maps should be ray traced when a world is built. These maps can then be referenced by geometry having the reflection attribute. == July 1, 2000 == * Added a special object structure to the BSP tree building code which allows special effects such as fire to exist in the global tree, and thus drawn in the correct back-to-front order with respect to other transparent structures. * Designed the mechanism for loading and saving world editor data and implemented C++ class serialization for all Ray Tracer objects. * Implemented support for the <code>GL_EXT_texture_edge_clamp</code> extension. * Added support for command shortcut keys in the Window Manager. * Implemented the ability to resize windows with real-time feedback. * Implemented texture map copy-back from the frame buffer. This will be used to copy the contents of a 3D viewport back into a window's texture array whenever the viewport is updated. * Added orthographic projection support to the 3D viewport dialog element. * Changed the MacOS sound streaming thread from cooperative to preemptive, now that the operating system can handle file access in preemptive threads. * Improved operating system event handling for both Windows and MacOS builds. * Made the necessary changes to build the engine with Visual C++. Going from a standard-conformant compiler to Microsoft's lame compiler is a royal pain. * Finished the File Manager reference documentation. == June 24, 2000 == * Implemented dynamic level of detail for all world structures. The level of detail is chosen based on the size of each structure, its distance from the camera, and a user-defined bias. * Implemented BSP tree order rendering for transparent world structures. Transparent structures are now rendered in back to front order after all opaque structures and after all movable objects. * Added flags field to the <code>Node</code> class in the World Builder. These flags let the World Builder know that each subnode shares some special property with the other subnodes on the same branch. For instance, this allows one to create a detail group in which every object must change its level of detail at the same time. * Added flag to the <code>Geometry</code> class which controls whether mipmaps are generated for its light map. * Added scorch marks for grenade explosions in the game module. == June 17, 2000 == * Added <code>Cone</code> geometry class to the World Builder. * Implemented collision detection for cone structures. * Added maximum slope cut-off in the collision detection system. This prevents characters from walking up inclines that are too steep. * Added better controls for curved surface subdivision to the World Builder. * Added support for alternate texture map and light map natural parameterizations to the World Builder. * Improved Sound Manager performance a bit. == June 10, 2000 == * Implemented general surface marking system. Scorch marks and blood splatters can now be applied to any surface in the game. * Added normalize render state to the <code>Renderable</code> class. This enables or disables the <code>GL_NORMALIZE</code> state. * Moved the following windows to the game module: Title, Host Game, Join Game, Setup Player, Chat, and Scoreboard. * Added notification function to the game module that lets it know when it's queried for server information. * Improved Memory Manager copy and fill performance. * Wrote reference documentation for the game module functions which are called from the Message Manager. == June 3, 2000 == * Modified the Message Manager sending algorithm to better handle high volume outgoing message traffic. * Added automatic port selection to the Network Manager. * Added message flags to the Message class which specify special properties such as whether the message should be sent reliably. * Finished the Network Manager reference documentation. * Worked on reference documentation for the File Manager, Time Manager, and Utility Library. == May 27, 2000 == * Added a network status window which displays the state of the network packet buffers. * Beefed up security in the Network Manager to better handle junk packet attacks. * Worked around an evil nasty bug in WinSock that can cause the wrong data to get sent across the wire. * Added the protocol number to the server query broadcast message. * Finished the Message Manager reference documentation. * Started the Network Manager reference documentation. == May 20, 2000 == * Added 32-bit parameter to network control packets. * Moved protocol check to the Network Manager level. * Moved max connections check to the Network Manager level. * Improved packet encryption architecture a little bit. * Added settings for reliable packet resend attempts. * Beefed up network file transfer architecture. * Added file request and transfer completion code to the download window. * Moved chat message display code into the game module. * Improved handling of connection timeouts. == May 13, 2000 == * Finalized client-server network topology implementation. * Added connect, disconnect, and timeout messages for notifying other players when someone enters or leaves a game. * Added client orientation state update messages which are sent to the server at regular intervals. * Fixed a rare problem in which the wrong texture map can get used right after another texture map is updated. * Fixed a problem in which repetitively hitting the escape or tilde key could cause these keys to stop being recognized. == May 6, 2000 == * Added a function to the World Manager which places a sound source in the world and applies all of the necessary spatialization effects. * Added a modifier matrix to the <code>Bone</code> class. This allows an additional transform to be applied to a bone after the animation transform is applied. * Added spine twisting to the <code>Soldier</code> class. No matter what animation is playing, the soldier now smoothly twists his upper body to point in the direction that the player is looking. * Implemented tumbling motion for the <code>Grenade</code> projectile. * Added a small random delay to sounds attached to a Fire object so that if someone spawns or teleports into an area where they can hear a bunch of torches, the sounds aren't all in phase. * Implemented random spawn location selection. * Fixed a small problem with the OpenGL material state change code in the <code>Renderable</code> execution pipeline. == April 29, 2000 == * Finished complete support for EAX environmental audio extensions. * Added Environment component class to the world editor. Environments define certain properties, such as acoustics, that apply to a region of the world. * Implemented secondary BSP tree for environment volumes. EAX listener properties are now modified depending on which environment the camera is located in. * Added <code>Material</code> class to the world editor. Material information is now referenced by every piece of geometry in the world and describes characteristics such as elasticity, frictional properties, and acoustical properties. * Implemented sound source obstruction effects. When a spatialized sound is played, the material of any structure between the sound source and the listener is used to apply obstruction effects to the sound. * Added <code>Location</code> marker class to the world editor. This is used for things like spawn locations and teleport destinations. * Moved most byte-swapping code into the structures on which they operate. * Added better diagnostics to engine initialization code. * Improved default scorch mark texture map. * Added Audio Settings window. == April 22, 2000 == * Added "Anchor to Origin" option to animation import dialog. This allows you to force a character to remain at the same position throughout an animation which would normally carry the character away from the origin. * Implemented Fighter player class in the game module. This class serves as a base for the other player classes and takes care of simple motion sequences such as running, jumping, and turning. * Added <code>MaterializeEffect</code> particle system to the game module. * Redesigned default particle texture map -- looks much better now. * Added support for material diffuse colors to the <code>Renderable</code> class. * Added fading functionality to the <code>Model</code> class. * Expanded input configuration window to support an unlimited number of controls. * Implemented basic support for EAX environmental audio extensions. == April 15, 2000 == * Implemented line-of-sight obstruction determination. This is similar to collision detection, but doesn't look for the nearest collision and doesn't return any information about the point of collision itself. It's just a yes or no answer to the question "Can I see point A from point B?". * Wrote surface marking system for scorch marks, blood splatters, etc. * Added collision handling routines for projectiles. * Implemented character-environment interactive collision detection, including sliding on walls and climbing stairs. * Wrote <code>ChaseCamera</code> camera class for following players around. * Added <code>Grenade</code> projectile class to the game module. * Added weapon switching controls to the game module. * Implemented multiple world editor viewport configurations. * Added routine to the math library that takes an arbitrary 3D vector and returns another vector which is perpendicular to it. == April 8, 2000 == * Implemented global collision detection. * Ripped out animation sequencing code -- I'm not happy with it. * Added frustum primitive geometry type (for visualizing cylinder-frustum intersection tests). * Added shadow outline display for model debugging purposes. * Beefed up shadow edge finder to handle edges shared by more than two triangles. * Implemented weapon swapping code in the <code>Soldier</code> class. == April 1, 2000 == * Added build progress window. * Began working on the world editor window. * Added code to clamp the cursor to the active monitor's rectangle. * Fixed case when fog settings would not get restored after changing monitor resolutions. * Added minimum and maximum values to <code>Animator</code> class. * Added automatic transform/position updating to the <code>Model</code> class. This is used for animation loops and transitions in which the model has been moved away from the origin. The position and orientation of the model is smoothly updated at the point that the animation loops or blends into another animation sequence. * Added <code>Soldier</code> player class to the game module. * Added <code>PlasmaGun</code> weapon class to the game module. == March 25, 2000 == * Improved BSP tree construction so that fewer nodes are created. * Added ability to have a projectile with no model so that projectiles made completely out of particles could be used. * Took out <code>ParticleType</code> data type and changed <code>ParticleSystem</code> class so that you have to explicitly specify a texture map. * Implemented plasma burst projectile. * Added input action for firing your gun. * Wrote animation sequencing system. This includes all animation transitions and all frame-based events (for things like sound effects). == March 18, 2000 == * Added a stats windows that lists how many vertices, faces, structures, etc., were rendered in a single frame. * Removed sub-namespace for the Ray Tracer components and renamed some classes to avoid conflicts with class names in the C4 namespace. * Added plane-frustum intersection test to the Camera class. * Implemented BSP tree visibility culling. * Added subclasses to the Structure class to accommodate specialized collision detection. == March 11, 2000 == * Implemented cylinder-frustum intersection test. This algorithm will appear in the forthcoming book [http://gameenginegems.com/gemsdb/book.php?id=3 ''Game Programming Gems'']. * Applied cylinder visibility test to shadow volumes. * Finished BSP tree construction code in the World Builder. * Put separate AltiVec build back into the project. * Added cylinder primitive geometry type (for bounding volume display). * Added plate primitive geometry type (for splitting plane display). * Added <code>Vector4D</code> class which is now used to represent planes. == March 4, 2000 == * Started game module project and moved all game-specific code to it. * Had to roll my own run-time libraries to get cross-module exception handling to work. * Updated config window to work with new input system features. * Implemented cube environment map generation in the World Builder. * Added supersampling settings to the Ray Tracer. == February 26, 2000 == * Hooked up input to the local player. * Generalized input system so that game-specific actions could be added. * Implemented spectator mode for when there is no local player. * Added precalculated per-frame bounding volumes to the animation resource. * Designed system for dynamically loaded game modules. == February 19, 2000 == * Implemented projection matrix based polygon offset. This technique will appear in the forthcoming book [http://gameenginegems.com/gemsdb/book.php?id=3 ''Game Programming Gems'']. * Generalized the system for run-time generated textures. * Established a division between general engine code and game-specific code. * Added rendering options to the Mesh class to allow the enabling or disabling of things like shadows. * Added light source attenuation factors. * Removed Pair template. * Added ability to install new console commands. == February 12, 2000 == * Added plasma particle type. * Designed generated texture for plasma flow. * Added even more texture mapping support to the 3D Studio MAX plugins. * Added animation modes to the model window. == February 5, 2000 == * Beefed up 3D Studio MAX plugins to greatly increase support for different texture mapping styles. * Rewrote model import system (mainly to extend mapping capabilities). * Added light sources to the world resource. * Finished model window functionality. * Improved stencil shadowing system. * Added <code>IconButton</code> interface element. == January 29, 2000 == * Added skeleton display to the model window. * Upgraded 3D Studio MAX plugins to support release 3.1 and added a way to extend the skeletal hierarchy. * Added Marker object class to the World Builder. This class holds the location and properties of intangible objects such as sound sources, special effects, and spawn locations. * Implemented a marker for the fire effect. * Added support for all OpenGL fog modes. * Added environmental properties to the world resource. These include things like ambient light and fog parameters. * Removed support for the <code>GL_EXT_clip_volume_hint</code> extension. It never makes any difference. == January 22, 2000 == * Removed <code>ColorARGB</code> class (all usages changed to <code>ColorRGBA</code>). * Added supersampling levels to lightmap generation. * Added ability to specify texture wrapping modes in s and t directions separately. * Added lightmap wrapping mode specification to Ray Tracer geometry classes. * Implemented box, disk, annulus, cylinder, and dome geometry classes in the Ray Tracer. * Implemented point and spot light classes in the Ray Tracer. * Added texture matrix to the <code>TextureMapAttribute</code> class. * Added ability to reverse normals for all geometry classes. * Hooked up diffuse color attribute to the World Builder. * Added ability to attach a sound to the fire effect. * Implemented screenshot function. == January 15, 2000 == * Implemented lightmap generation system in the Ray Tracer. * Added rendering order variable to the <code>Renderable</code> class so that transparent objects could be forced to render last. * Added function to the Time Manager for retrieving the current date and time. * Modified fire objects so that they all use the same dynamic texture instead of each one having its own. * Designed BSP tree architecture which allows the splitting planes to hold complex geometry. * Implemented Structure base class which holds the geometry for a BSP tree node. * Added tessellation system to the Ray Tracer for generating vertex data. * Designed file format for world geometry. * Wrote the World Builder -- this takes a scene from the world editor, builds a BSP tree, uses the Ray Tracer to generate light maps, and writes out a world resource. == January 8, 2000 == * Implemented system for generating cool electrical effects. * Added support for triangle fans, triangle strips, and quad strips. * Modified the Text Manager to allow easier addition of new fonts. * Generalized object type designation to allow easier addition of new object subclasses. * Overhauled the attribute system in the Ray Tracer so that it parallels the capabilities of 3D hardware. == December 25, 1999 == * Added fog render state to the <code>Renderable</code> class. * Added wireframe render state to the <code>Renderable</code> class. * Integrated cube environment map functionality into the texture combination algorithm. * Finished the unified <code>Renderable</code> execution pipeline. Everything in the engine which can be rendered is now sorted by the texture maps that it uses and by its rendering state. When the list of renderable objects is executed, all of the details of multitexture combinations, multiple passes, and state changes now happen automatically and in optimal order. * Added rendering options to the display settings. == December 18, 1999 == * Implemented texture combination modes and the multitexture/multipass algorithm. * Added support for the <code>GL_EXT_texture_env_add</code> extension. * Added stencil buffer render state to the <code>Renderable</code> class. * Implemented stencil buffer based shadowing system. Models can now cast shadows on their environment, other models, and even themselves. * Added animation controls to the model window. * Simplified the <code>StringID</code> type and removed the consequently no-longer-used Array template. == December 11, 1999 == * Added level of detail controls to the model import window. * Added level of detail functionality to the model window. * Began research on the global visibility and collision detection systems. * Added constant color render state to the <code>Renderable</code> class. * Implemented bounding volume display. == December 4, 1999 == * Added Windows support to font generator. * Tweaked font generation a little bit to produce better spacing. * Updated model resource format to let it take advantage of the recent rendering engine improvements. * Finished dynamic level of detail system for rigid and deformable meshes. * Began experimenting with fractal tree generation. == November 27, 1999 == * Implemented new generalized rendering architecture. Every renderable object is now subclassed from a new <code>Renderable</code> class which encapsulates all of the vertex buffer, texture, and state information needed to draw itself. * Included support for arbitrary multitexturing, which uses as many texture units as are available in hardware and reverts to multiple passes if there are more texture layers than the hardware can handle. * Added support for several vertex buffer primitives. * Modified several systems to use new vertex buffer types where appropriate. * Implemented sort-by-state rendering to minimize hardware state changes. * Improved texture map resource management. * Added <code>RemoveAll()</code> function to the <code>List</code> template. == November 20, 1999 == * Redesigned menu architecture. Every menu now exists as a separate window, allowing it to extend outside the window that it is attached to, as well as enabling some other effects. * Improved texture map dicing algorithm for window contents. * Fixed bug that screwed up shadows for windows with small height. * Integrated AltiVec build into standard MacOS build. The startup code now detects the AltiVec processor and sets some function pointers accordingly. * Implemented covariant normal transformation in the Ray Tracer. * Added support for the <code>GL_EXT_clip_volume_hint</code> extension. * Removed device list from control settings window. * Integrated font generation tool into C4 source. == November 13, 1999 == * Rewrote the Network Manager. There is now no limit on the number of simultaneous connections, and symmetric support for reliable and unreliable packets has been added. Also removed restriction on IP port numbers. * Changed <code>List</code> template so that adding an object to a list would automatically remove it from any other list that it was a member of, removing the need to call <code>Detach()</code>. * Added fix to the Input Manager to handle cases when the user presses multiple keys/buttons which map to the same action. aa739881664f19d34e514a874c59fc3eb56b35cc Release Notes for Build 108 0 13 15 2023-07-15T09:21:43Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' May 27, 2005 * Added the <code>kLightExternalZone</code> flag to the <code>LightObject</code> class. This tells the lighting system that the light may not be physically located in the zone that contains the light node in the scene graph. This flag is useful for lights that are attached to other objects (like a character). It's possible for a character to be in one zone, but the light that he's holding to be in a different zone because his a..." wikitext text/x-wiki __NOTOC__ '''Release date:''' May 27, 2005 * Added the <code>kLightExternalZone</code> flag to the <code>LightObject</code> class. This tells the lighting system that the light may not be physically located in the zone that contains the light node in the scene graph. This flag is useful for lights that are attached to other objects (like a character). It's possible for a character to be in one zone, but the light that he's holding to be in a different zone because his arm extends through a portal. Setting the flag allows the lighting system to build the light's illumination tree correctly at the slight expense of having to find the zone that contains the light. * Added a tool tip mechanism to the Interface Manager. Any renderable interface element can now have tip text assigned to it, and this text will appear in a little pop-up box whenever the cursor hovers over the element for half a second. Tool tips were added to all of the World Editor palettes. * Added mouse wheel zooming to the World Editor. Mouse wheel support was also added to the <code>ListBoxElement</code> class. * Changed the way that portals are rendered in the World Editor. It's much easier to see a portal now when you're looking directly at its face (perpendicular to its plane) and its edges coincide with scene geometry. * Fixed a model export bug in the World Editor. * Added a simple progress bar interface element. * Added more picking capabilities to the <code>GeometryManipulator</code> class. Previously, only geometries that had collision data could be directly selected because the collision detection system is used to pick geometries in the World Editor. Now, a fallback routine takes over for geometries without collision data that just tests a ray against the triangle soup. * Finished updating the Movie Player tool. 9fb2e19aa8b5a6cac737329a91f06c346cd5c005 Release Notes for Build 109 0 14 16 2023-07-15T09:22:14Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' June 23, 2005 * Added the <code>PaneBoxElement</code> interface element. This provides a tabbed box that can be used for switching among panes containing different groups of settings. * Rearranged the material attribute settings to use multiple panes. * Added reflection and refraction settings to the material manager. These can be used with remote portals by specifying that the image rendered a remote portal is to be directed to either..." wikitext text/x-wiki __NOTOC__ '''Release date:''' June 23, 2005 * Added the <code>PaneBoxElement</code> interface element. This provides a tabbed box that can be used for switching among panes containing different groups of settings. * Rearranged the material attribute settings to use multiple panes. * Added reflection and refraction settings to the material manager. These can be used with remote portals by specifying that the image rendered a remote portal is to be directed to either the reflection buffer or the refraction buffer. There is no NV20 fallback for this functionality yet. * Added support in the Graphics Manager and for reflection and refraction buffers. A remote portal can now indicate that what it sees can be rendered to one of these buffers instead of the primary buffer. The buffers can then be used as texture maps in the primary rendering pass so that effects like bumpy reflection and refraction are possible. * Added a feature mask the the Graphics Manager. This allows certain rendering features to be enabled or disabled for some extra performance tuning ability on lower-end GPUs. It's also used for disabling features that aren't shown in the World Editor. * The Unpacker class now stores the version number from the file being loaded. This allows unpacking functions to perform certain actions only if the version number is high enough so that backwards compatibility is more easily maintained. * Changed the popup menu in the World Editor's controller assignment window to a list box. * Added registration mechanisms for location and position markers. Types of locations and positions don't have to be registered, but if they are, the World Manager displays them in a list box now in the Get Info window. * Renamed the <code>Controller::Create()</code> function to <code>Controller::EnterWorld()</code> to make it more clear what it's actually used for. * This build includes an Xcode project file for MacOS X. The engine runs full-featured on the Mac, build there are some issues with Apple's OpenGL implementation that will never be resolved unless a miracle occurs and Apple starts to care about games and middleware. * Preliminary fog functionality is now implemented as a post-processing effect. This works fine on Nvidia hardware, but currently gets stuck in a software mode under ATI drivers. We have just been informed that ATI hardware does not support copies from the depth buffer to a texture, so we need to develop an alternative. Also, there is no NV20 fallback yet. * Finished implementing good menu bar behavior. Mouse interaction with pulldown menus now works like you would expect. ba79f796fb1b4add90e08895c22f64e24f16cb36 Release Notes for Build 110 0 15 17 2023-07-15T09:22:47Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' July 5, 2005 * Made some adjustments so that the projects will build correctly on the Mac using Xcode 2.0. * The main project now compiles and links successfully under Dev-cpp. However, there are still issues preventing the game module and tools from being linked to the main executable. * Removed the requirement that the <code>GL_ARB_fragment_program_shadow</code> extension be available in order to get the ARB1 shader path. The Mac and..." wikitext text/x-wiki __NOTOC__ '''Release date:''' July 5, 2005 * Made some adjustments so that the projects will build correctly on the Mac using Xcode 2.0. * The main project now compiles and links successfully under Dev-cpp. However, there are still issues preventing the game module and tools from being linked to the main executable. * Removed the requirement that the <code>GL_ARB_fragment_program_shadow</code> extension be available in order to get the ARB1 shader path. The Mac and some notebook graphics drivers don't expose this and it forced the engine into the NV20 path. * Added a safety mechanism to the string table resource so that attempting to retrieve a string whose identifier doesn't exist causes the string "<missing>" to be returned. * Added support for 24-bit TGA files in the Texture Importer tool. It will now accept 16-bit, 24-bit, and 32-bit images, either compressed or uncompressed. * Removed an experimental deferred lighting effect. Not enough bang for the buck. 5895479bad026221cd8d2fc6766720b0c6f6d90e Release Notes for Build 111 0 16 18 2023-07-15T09:25:35Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' July 26, 2005 * Fixed a minor glitch in the light region determination code that could cause light regions generated by large portals to be too small. This only affected point lights, and could cause the illumination to drop out too early as the camera turned away from the portal. * Implemented a new diagnostic mechanism that displays light regions. This is toggled on/off by using the command <code>rgns</code> in the command console. The..." wikitext text/x-wiki __NOTOC__ '''Release date:''' July 26, 2005 * Fixed a minor glitch in the light region determination code that could cause light regions generated by large portals to be too small. This only affected point lights, and could cause the illumination to drop out too early as the camera turned away from the portal. * Implemented a new diagnostic mechanism that displays light regions. This is toggled on/off by using the command <code>rgns</code> in the command console. The green lines that are shown represent the edges of the light regions generated by portals for every light source that can shine through a portal. Only geometry intersecting any particular light region is considered to be potentially lit by the light source generating the region. * Changed the <code>Controller::Activate()</code> function so that it takes an additional parameter that indicates which trigger node caused the controller to be activated, if any. See the function documentation at [http://c4engine.com/docs/Controller/Controller_Activate.html <code>Controller::Activate</code>]. * Fixed a small problem in which the <code>BoxGeometryObject</code> primitive would not generate the right polygons if the number of subdivisions in the x and y directions were not the same. * Added the <code>kNodeGenerateInhibit</code> flag to the flags that can be set for the Node class. This flag prevents the node from participating in resource generation (shadow maps, environment maps, and ambient maps). * Added a flexibility array to the fluid geometry. This controls how much each vertex in a fluid is able to move so that non-square borders can be used with a fluid surface. * Added the option to include an uncompressed fallback format when importing a texture map and using S3TC compression. (If a texture resource contains both compressed and uncompressed images, only the one that's actually used gets loaded. 9f45ebd8fe460981f07cd3be8a3d74ae9f211839 Release Notes for Build 112 0 17 19 2023-07-15T09:27:40Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' October 19, 2005 * This build includes a heavily commented sample game module called "Skeleton" that represents nearly the minimum amount of code that needs to be written to have a working game module. You can tell the engine to load this game module by editing the file <code>Data/CFG/Variables.cfg</code> and changing the value of the variable <code>$applicName</code> to "Skeleton". To get the primary game module back, change <code>$applicN..." wikitext text/x-wiki __NOTOC__ '''Release date:''' October 19, 2005 * This build includes a heavily commented sample game module called "Skeleton" that represents nearly the minimum amount of code that needs to be written to have a working game module. You can tell the engine to load this game module by editing the file <code>Data/CFG/Variables.cfg</code> and changing the value of the variable <code>$applicName</code> to "Skeleton". To get the primary game module back, change <code>$applicName</code> to "Game" again. * Implemented a large amount of new collision detection functionality. The existing function <code>World::DetectCollision()</code> is still present and should continue to be used for line-of-sight tests and sphere-environment collision tests. There is now a new function for capsule collisions, <code>World::DetectCapsuleCollision()</code>, and it detects collisions between an arbitrary swept capsule and the environment. Both of these functions are precise to the polygon level and are implemented using continuous techniques (as opposed to iterative techniques). This means the collision detection is tunnel-proof. * For most types of moving objects, it is now best to use the new <code>Collider</code> class for collision detection instead of calling the above functions directly. The <code>Collider</code> class has two subclasses, <code>SphereCollider</code> and <code>CapsuleCollider</code>. Each controller class corresponding to a moving object should inherit from one of these two <code>Collider</code> subclasses. Then the controller's <code>Move()</code> function simply specifies the starting position and delta for the current frame. After all controllers have moved, the collision detection among all colliders is performed, and then the <code>Travel()</code> function of each collider class is called. At this point, the <code>Collider</code> class contains a collision state that indicates whether a collision occurred and, if so, whether it was with the environment or another collider. The implementation of the <code>Travel()</code> function can do whatever it wants in response. * See the <code>BallController</code> class in the <code>Skeleton.*</code> files for an example showing how to use the new collision system. To see a cool stress test, load the world called "Test" while running the Skeleton application module by entering <code>load test</code> in the command console. (Nothing will happen in this room if running the big game module.) * The engine module now contains stock controller base classes for basic projectiles and characters. The <code>ProjectileController</code> class is subclassed from <code>SphereCollider</code> and handles the motion of simple projectiles under the influence of gravity and/or through a resistive medium. The <code>CharacterController</code> class is subclassed from <code>CapsuleCollider</code> and handles things like gravity, falling off of things, sliding against walls, and climbing ramps. * Updated the sample game module to use the new collision system and controller base classes. Projectiles will now hit each other, so it's possible to shoot down rockets, etc. The game module class <code>FighterController</code> is now in a clean state and handles player movement, character collisions, weapon firing, and projectile hits. * The game module contains a class called <code>FighterController</code> that is a subclass of the <code>CharacterController</code> and handles more details of the player movement. It's pretty functional right now, but is still a work in progress in some ways. In particular, it doesn't currently spend any time trying to detect whether the character is climbing stairs, but some research is being done to determine whether this is practical and worth the extra computational expense. Right now, it's best to cover stairs with an invisible ramp for smooth character movement. * The <code>FighterController</code> doesn't currently implement client prediction for multiplayer games, but it will soon. The previous code, which was very hacky, has been removed. * Added shader level of detail for parallax mapping. When enabled, the scale of the parallax effect will gradually decrease to zero at the transition point from level 0 to level 1, and parallax mapping is reduced to ordinary bump mapping in level 1 and above. * Implemented full support for Cook-Torrance specular reflection via the MicrofacetAttribute material attribute. Both isotropic and anisotropic microfacet distributions are supported, but the geometrical attenuation factor has been omitted because it almost always makes an unnoticeable difference. '''Note:''' Microfacet shading has been disabled for all types of lights except infinite lights due to some pending changes in the shader building code. It will be fully functional in the next release. * Added the <code>$featureDisableMask</code> permanent system variable. This has 1-bits for any graphics features that are explicitly disabled by the user. Updated the graphics settings dialog to allow parallax mapping and microfacet shading to be turned on/off. * Added the <code>kShaderCubeLightInhibit</code> shader flag that prevents a cube light projection from being rendered on a geometry. This is useful when applied to the geometry surrounding a cube light source (that is actually casting the projected shadow) so that it doesn't receive its own shadow. * Updated the Sound Player tool. It now displays the wave being played as it used to under the old windowing system, and there is a volume control. * The sound mixer now supports 22.05 kHz stereo sounds, both streaming and non-streaming. All mono and stereo sounds that are either 22.05 kHz or 44.1 kHz are now supported. * Modified the free camera tool in both the World Editor and Model Viewer so that the camera accelerates like the spectator camera does. * Added the <code>PropertyObject</code> class. This serves as a shared container for an arbitrary list of properties, and it can be attached to nodes just like material objects. Thus, changing any of the properties affects all nodes using the property object. There's currently no interface for this in the World Editor, but it will be present in a later release. * Added the <code>Collection</code> node. This is a container that holds a set of key/node pairs. There's currently no interface for this in the World Editor, but it will be present in a later release. * There is now a new <code>EnvironmentMapAttribute</code> that can specify a texture map that will override the environment map assigned to the zone containing an object. This attribute should be applied in addition to the <code>EnvironmentAttribute</code> to take effect. It can be specified in the Textures pane in the World Editor's material manager. * Added a constructor and <code>Set()</code> overload for the <code>Vector4D</code> class that take a <code>Vector3D</code> and a <code>Point3D</code>. These are interpreted as the normal direction of a plane and a point lying in that plane. The normal is copied into the <code>x, y</code>, and <code>z</code> components, and the <code>w</code> component is given the value <code>-Dot(n, p)</code>. * All of the random number functions have been moved into the <code>Math</code> namespace. This includes <code>Random(), RandomFloat(), RandomUnitVector(), RandomUnitQuaternion(), GetRandomSeed(),</code> and <code>SetRandomSeed()</code>. These functions either need to be qualified with <code>Math::</code> or the statement using namespace <code>C4::Math;</code> needs to appear in any source file that uses them. * Defined an integer type called <code>natural</code> that corresponds to the natural register width on the target machine. This type should be used for variables which are expected to be kept in CPU registers so that arithmetic is performed on them at the machine's natural size, avoiding extra sign extensions or high-word clears. Defining the natural type is primarily a performance optimization for the 64-bit PowerPC architecture. * Made lots of various minor additions and improvements to the primary game module. * The Visual Studio project files have been updated to be easier to move to different machines and easier to convert to later versions. * This release contains temporary plugins for Maya, but these are going to be replaced by the Collada format in the next release. * The source texture map for the terrain in the demo is included in this release. It's path is <code>Data/TEX/terrain/Lake.tex</code>. 05f092b60773d01ae8781f3c92b2582476e8258c Release Notes for Build 113 0 18 20 2023-07-15T09:28:22Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' December 26, 2005 * '''WARNING:''' It is strongly recommended that you backup <code>WLD</code> and <code>MDL</code> resources before upgrading to this version of the code. The geometry serialization format has changed a little, and existing resources will automatically be updated to the new format when they are loaded and then saved (see next item). Although no problems are anticipated, a backup of your old files should be kept until you're..." wikitext text/x-wiki __NOTOC__ '''Release date:''' December 26, 2005 * '''WARNING:''' It is strongly recommended that you backup <code>WLD</code> and <code>MDL</code> resources before upgrading to this version of the code. The geometry serialization format has changed a little, and existing resources will automatically be updated to the new format when they are loaded and then saved (see next item). Although no problems are anticipated, a backup of your old files should be kept until you're sure the updated files are able to be loaded. * The geometry data format has been changed a little bit, and some extra information has been removed from the array structures stored in the <code>GeometryLevel</code> class. The engine will still read the old format, but it is recommended that all worlds and models be updated to the new format. To update a world, all you have to do is open the world in the editor and then just save it. You can update a model by opening it in the model viewer and saving it using the Save item under the Model menu. <code>WLD</code> and <code>MDL</code> files will generally shrink by an average of 3% to 7%. All new files are saved in the new format. * Support for NV2x hardware has been removed, along with several thousand lines of shader code. The result is that the rendering core of the engine is much cleaner, the data structures used for shading are smaller, and several ugly pieces of special-case code have been removed. A lot of work had been put into the NV2x shading code a few years ago, so it's sad to see it go, but after careful consideration, it was decided that it was bad for the engine's future to keep it around. Some of the reasons for the cut were 1) we never supported ATI hardware from the same generation, 2) the NV2x shading code was the only rendering path that required multiple passes per light, and 3) Nvidia has not implemented FBO functionality for NV2x chips. * This build includes the first release of the Collada format import tool. This tool supports version 1.3.x of the Collada format, and version 1.4 will be supported once the specification has been finalized. * The Collada export plugins write files with the <code>DAE</code> extension. Place these in the <code>Import/DAE/</code> directory, and they will be found by the Collada import tool. To import geometry from a Collada file, select Import Geometry from the World menu in the world editor. The import tool will recognize and import the node hierarchy, instanced geometries, instanced light sources, skinning information, material information, and animations. * Once something has been imported into the world editor, it can be turned into an entity by using the Export Model command under the World menu. You can make changes to the imported geometry first if necessary. An exported model can be opened in the model viewer, and animations can be applied using the Import button. Animations for a particular model need to be stored in a subdirectory having the same name as the imported model. For example, if you import a Collada file named <code>Monster.dae</code> (in the <code>Import/DAE/</code> directory), then all the animations for that model should be stored in the <code>Import/DAE/Monster/</code> directory. * The import dialogs for both importing geometries and animations have a popup menu at the bottom that lets you select an import tool. The Collada importer is active by default, but the old 3DS Max importer is there as well. When you select the Max importer, the source directory will change to <code>Import/C4G/</code> (for geometries) or <code>Import/C4A/''<name>''/</code> (for animations). * '''Note:''' There appears to be a bug in the Collada export plugin for 3D Studio Max that generates bad skinning data. This is an issue with the export plugin provided by Autodesk and is beyond our control. Until the issue is resolved, you still need to use the old Max plugins for skinned models. (Skinned models exported from Maya work fine.) * Animation interpolation has been improved, and it is now possible to change the animation rate. The <code>Entity::SetAnimationRate()</code> function sets the animation rate in frames per millisecond. * Added a new particle system feature that places particles at infinity. This is useful for placing objects infinitely far away in the sky. Specifying the <code>kParticleSystemInfinite</code> flag for a particle system will cause the particles to be rendered at infinity, and the radius of each particle is then interpreted as a percentage of the horizontal field of view. * The <code>StarField</code> particle system has been added to the sample game module. It reads star positions and intensities out of a <code>FLD</code> resource and generates a particle system that places the stars at infinity in the sky. Currently, the positions of the 12,000 brightest stars visible from Earth will be read from the file. A star field is placed in a world by adding a location marker with the "Star field" type. An example world named "Earth" has been included which contains two spheres representing the Earth and the moon, and the star field. * Support for framebuffer objects (FBOs) has been added to the Graphics Manager. Currently, this will only be used on Nvidia hardware under Windows because they are the only ones who have implemented it to a usable degree (meaning they support <code>EXT_packed_depth_stencil</code>). This build includes a glow post-processing effect that uses the FBO functionality, and more effects will be added soon. * Implemented a glow post-processing effect. Glow is automatically applied whenever a glow-enabled object is rendered in the scene. Currently, a skybox can be made to glow by checking the "Enable skybox glow" box in the World Settings dialog. The textures used in a glowing skybox should contain alpha channels representing the glow intensity. Glow for ordinary geometries is determined by the emission attribute in their materials. The emission alpha determines the glow intensity, and this is taken from the emission color or emission texture (or the product of the two if they are both present). For a geometry to glow, the "Enable emission glow" box must be checked in its Get Info dialog. * There is now a new alpha channel format that can be selected in the Texture Importer tool called "Glow Intensity". This should be selected for textures used as emission maps or skybox faces that should have the glow effect applied to them. * Several global rendering options have been exposed in the Graphics Options dialog. Among them are control over bilinear/trilinear/anisotropic texture filtering and enable switches for parallax mapping, microfacet shading, and higher-quality bump mapping. Some of these options were previously controlled using the <code>$featureDisableMask</code> variable, but each option now has its own variable (and <code>$featureDisableMask</code> has been removed). * Microfacet shading (Cook-Torrance) is now fully implemented for all light types. * The <code>CharacterController</code> code has been updated to handle some nasty corner cases, and a lot of the functionality that used to be in the <code>FighterController</code> class of the sample game module has been moved to the <code>CharacterController</code> base class. More tweaks are planned for this class in near-term releases. * Two new functions, <code>LookAtPoint()</code> and <code>LookInDirection()</code>, have been added to the <code>Camera</code> class, and they do exactly what they sound like they do. For details, see the documentation at [http://www.terathon.com/c4engine/doco/WorldMgr/Camera.html <code>Camera</code>]. * Added the <code>C4Spatial.h</code> file that contains generic structures for octrees, quadtrees, bintrees. * Added the <code>AlignedBox</code> class to the <code>C4Bounding.*</code> files to represent an axis-aligned bounding box. * Added the <code>ProjectOnto()</code> function that projects one 2D/3D/4D vector onto another. * It's now possible to set a clear color in the world editor. Normally, the color buffer is not cleared before rendering because the whole screen will be filled by geometry. However, in some scenes such as a space environment, it's convenient to be able to specify a clear color instead of using a solid-color skybox. If a clear color is selected in the World Settings dialog, the color buffer is cleared to that color before rendering occurs for each camera. Note that using the clear color will prevent remote portals that render to the primary buffer from working. * Added the Select All by Mask command to the Edit menu in the World Editor. Unlike the ordinary Select All command, this respects the current selection mask. * Added a toggle button to the World Editor for showing backfaces in wireframe. This also allows planar geometries to be seen when viewed edge-on in an orthographic viewport. * The world editor now generates picking rays that account for the bounding sphere of the whole world. Some huge worlds were experiencing problems because the 2km range of the previous rays was too small, causing some items to be unselectable. * Leak detection functionality in the Memory Manager has been improved. There is now a preprocessor define at the top of <code>C4Base.h</code> called <code>LEAK_DETECTION</code> that controls whether this functionality is enabled. To turn leak detection on, set <code>LEAK_DETECTION</code> to 1 and recompile. When you run the engine with leak detection, exercise all of the code you want to test, and then quit the engine. Right before exiting, the engine will write out the file <code>leaks.txt</code> in the same directory as <code>C4.exe</code>. This file contains a list of unfreed memory blocks along with the allocation count, filename, and line number at which each was allocated. 8291947ce5cac37fc15c496b3b02bab6759cf515 Release Notes for Build 114 0 19 21 2023-07-15T09:29:58Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' January 9, 2006 * Fog has been completely redesigned in this build. Fog is no longer a property of a zone, and any existing uses of the old fog property will disappear from worlds opened in this build. Fog is now controlled by placing a fog space node into the scene. The zone containing the fog space node is automatically fogged, and other zones may be linked to the fog space so that one fog space can be used to fog areas covered by more th..." wikitext text/x-wiki __NOTOC__ '''Release date:''' January 9, 2006 * Fog has been completely redesigned in this build. Fog is no longer a property of a zone, and any existing uses of the old fog property will disappear from worlds opened in this build. Fog is now controlled by placing a fog space node into the scene. The zone containing the fog space node is automatically fogged, and other zones may be linked to the fog space so that one fog space can be used to fog areas covered by more than one zone. The fog space itself defines a boundary plane between fogged and unfogged half-spaces. The half-space on the negative side of the plane contains fog, and the half-space on the positive side of the plane is clear. A single formula is used to handle the four possible configurations between a camera and an arbitrary point in the scene. (The camera can either by in the fog half-space or in the clear half-space, and a surface point can be on either side of the plane.) In all cases, the amount of fog applied to a fragment is determined by the distance along the direction from the surface point to the camera that actually lies on the fogged side of the plane. Fog is applied to everything, and it is integrated into the existing rendering passes. There is no post-processing calculation. * A world may contain multiple fog spaces, but only one can be active at any time for a particular camera view with defined results. It's okay for one fog space to be used in a zone directly visible to the primary camera and then for another fog space to be seen through a remote portal. This works because the image seen through the remote portal is rendered from a different camera. * Fog can be rendered in two modes. By default, fog is computed at each fragment to yield an accurate result regardless of the position of the fog plane or an object's degree of tessellation. This can have performance implications, however, so it is also possible to force the fog distance to be computed on a per-vertex basis. Doing this on Nvidia hardware is especially fast because it can take advantage of dedicated fog silicon that reduces the per-fragment cost to virtually zero (but this has limited precision). Since the interpolated fog distance for large polygons can get quite inaccurate far from the vertices, calculating fog distance per-vertex generally requires higher levels of tessellation. In this mode, it's also necessary to split polygons at the fog plane so that positive fog distances don't get extrapolated outside the fogged half-space. The geometry flags now contain a setting for splitting polygons automatically at the fog plane referenced by the geometry's owning zone. * A fog space is created in the editor using the fog space tool in the light/sound/space panel. Only the plane of the fog space matters—the rectangular size can be anything you want. Additional zones can be linked to the fog space by first making the fog space the current target (Ctrl-T), then selecting one or more zones, and finally choosing Link to Target (Ctrl-L). The zone actually containing the fog space does not need to be explicitly linked. * As a performance optimization, direct portals may have a flag set that prevents fog from being rendered through them. This is useful if the portal looks into a zone containing fog, but it is known that none of the fogged area can be seen from the other side of the portal. * Occlusion portals are now fully implemented. (These have been available in the editor, but were ignored by the visibility code in previous builds.) Also known as an antiportal, an occlusion portal prevents objects that are behind it from being rendered. An occlusion portal is not linked to a destination zone and is usually placed in the middle of a zone inside some large object that blocks a lot of things from view. Any geometry, light, portal, or effect that is completely blocked by an occlusion portal from the camera's perspective is not considered any further for rendering. In general, occlusion portals should be as large as possible so that culling is maximized, and the number of occlusion portals visible at any one time should be kept as low as possible to minimize CPU calculations. Note that occlusion portals may not always produce big speed improvements where you think they should because of good hardware z-culling. * Added the <code>SetOcclusionProc()</code> function to the Node class and modified the existing <code>SetVisibilityProc()</code> function. The procedure installed by the <code>SetVisibilityProc()</code> function now takes a pointer to a single <code>ZoneRegion</code> and must determine whether a node is visible within that region. The procedure installed by the <code>SetOcclusionProc()</code> function takes a pointer to a list of <code>ZoneRegion</code> objects and must determine of a node is occluded within any of them. See the documentation at [http://c4engine.com/docs/WorldMgr/Node.html http://c4engine.com/docs/WorldMgr/Node.html] for details. By default, a node's visibility and occlusion procedures check the node's bounding sphere against a region's bounding planes using the functions provided in the <code>Region</code> class. Several geometry primitives override this behavior to use tighter bounding volumes like boxes or cylinders. * Ordinarily, a game module only needs to worry about visibility and occlusion procedures for special effect classes derived from the <code>Effect</code> node. An effect needs to either provide a bounding sphere (by overriding the <code>Node::CalculateBoundingSphere()</code> function) or needs to install a visibility procedure and an occlusion procedure. The <code>Render()</code> function of an effect no longer needs to test for visibility and will only be called if the effect is enabled, visible, and unoccluded. See the documentation at [http://c4engine.com/docs/EffectMgr/Effect_Render.html http://c4engine.com/docs/EffectMgr/Effect_Render.html]. * Improved the way in which multi-zone effects are handled. Because some special effects can span mutiple zones (notably particle systems like smoke trails), their eligibility for rendering can't be determined solely based on whether their owning zones are visible. Being a scene graph node, an effect node can only be in one zone at a time, but there is a mechanism that lets any number of other zones reference the effect so that it will be considered for rendering whenever those zones are visible. By default, an effect is referenced by the zone that owns the effect node. If the effect defines a bounding sphere (by overriding the <code>Node::CalculateBoundingSphere()</code> function), then any zone into which that sphere extends through portals also references the effect. This ensures, for instance, that particles from an explosion that fly into another zone are visible to someone who can't see the zone containing the effect node itself. * An effect may override the default zone-referencing behavior by disabling the post-bounding-sphere calculation. This is done by adding the following line to an effect's constructor or <code>Preprocess()</code> function: <code>SetActiveUpdateFlags(GetActiveUpdateFlags() & ~kUpdatePostBounding);</code> * If this is done, then the effect is responsible for explicitly adding references to zones from which the effect could be visible. The <code>Effect::AddEffectReference()</code> and <code>Effect::RemoveEffectReference()</code> functions are supplied to do this. It is often convenient to call these from within overridden <code>EnterZone()</code> and <code>ExitZone()</code> functions. For more details, see the documentation at [http://c4engine.com/docs/EffectMgr/Effect.html http://c4engine.com/docs/EffectMgr/Effect.html]. * The Display Manager will now choose the highest refresh frequency available for any particular resolution when in fullscreen mode. Previously, it let the driver choose the frequency, but this seems to have always resulted in the somewhat low 60 Hz refresh rate. * Made various vertex program and fragment program improvements after observing how the driver was compiling them on both Nvidia and ATI hardware. The engine now contains some conditionally-compiled hooks that lets an external tool capture the actual hardware command buffer, from which it's possible to gain a lot of information about exactly what is being done on the hardware. (Sorry, this tool cannot be released.) * The command console now stores a small command history that can be accessed with the up and down arrows. * Changed what used to be called "focal length" for a spot light to "apex tangent". The term "focal length" was borrowed from the same property that a camera has in relation to its field of view, but it's a little confusing when it's applied to spot lights. The apex tangent t is the trigonometric tangent of half of the horizontal field of illumination. That is, at a distance t from the spot light's center in the direction that it's pointing, the pyramid of illumination has widened to one unit left and right. * A new tool is shown in the World Editor that will let you select objects by dragging out a box, but this is not yet implemented and will have no effect if used. * Fixed a small bug in the World Settings dialog that always caused the skybox glow enable box to be unchecked when the window is opened. (The skybox would still get the glow property if you checked the box and closed the window.) Also fixed a bug that would make it impossible to disable glow for a geometry once it was enabled. * Fixed a minor bug in which the brightness setting in the Graphics Options dialog was not being saved unless you changed the display resolution or fullscreen setting. Also made it so that changing only the brightness and then cancelling the dialog would restore the original brightness. * Fixed a bug that would generate a bad fragment program if specular color, microfacet color, and gloss map were all being used in a material. * Fixed a bug that prevented depth maps from being created in the previous build due to all of the shader system changes. 8aca51769a2dc7faa60f5feb106e1c0fe561d192 Release Notes for Build 115 0 20 22 2023-07-15T09:30:46Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' January 12, 2006 * This is a tune-up build that corrects some existing problems, most of which are rather minor, and makes various improvements in the sample game module. * Changed the way that grenades behave in the game module. Previously, the grenade controller determined that a grenade should stop when it collides with something if the velocity component along the collision normal was small enough. This caused the grenades to stick to..." wikitext text/x-wiki __NOTOC__ '''Release date:''' January 12, 2006 * This is a tune-up build that corrects some existing problems, most of which are rather minor, and makes various improvements in the sample game module. * Changed the way that grenades behave in the game module. Previously, the grenade controller determined that a grenade should stop when it collides with something if the velocity component along the collision normal was small enough. This caused the grenades to stick to surfaces if they were shot at a low enough angle even though they still had a lot of speed tangent to the surface. The grenade controller now takes the tangent velocity into consideration and won't stop a grenade that's still travelling too fast. * Modified the <code>CharacterController</code> in the engine module and <code>FighterController</code> class in the game module so that they allow the player to jump if he is within a certain distance of the ground instead of requiring that he actually be on the ground. Previously, a character running around on an uneven surface (like terrain) would have a hard time jumping because he frequently falls for very short distances and wouldn't technically be standing on the ground during those times. * Made some changes to the <code>CharacterController</code> that prevents the character from missing collisions with the terrain. However, the character can now get stuck in some corners if you try hard enough. I've come to the conclusion that using a curved surface for collisions against an arbitrary triangle mesh with smooth sliding is inherently non-robust, so the current system is temporary and will be replaced. * Moved the <code>SpectatorCamera</code> and <code>BenchmarkCamera</code> classes into the engine module and tweaked them a little bit. * The <code>MarkingData</code> structure used to be nested inside the <code>MarkingEffect</code>, but this was a little unwieldy. It's now defined outside <code>MarkingEffect</code>, so any previous declarations of <code>MarkingEffect::MarkingData</code> need to be changed to just <code>MarkingData</code>. * Fixed some bad collision settings in the demo level. 166f9db64e246ea2a5d1940cbef5c128f8d3bfb7 Release Notes for Build 116 0 21 23 2023-07-15T09:31:37Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' February 28, 2006 * The Get Info dialog in the World Editor has been expanded to include controller and texture mapping settings that used to be shown in separate windows. The Get Info dialog now has multiple tabs, and the Controller tab is always present. Geometries now have tabs for geometry building flags, rendering flags, collision properties, and texturing settings. * There are now a few additional tabs in the Get Info dialog: Genera..." wikitext text/x-wiki __NOTOC__ '''Release date:''' February 28, 2006 * The Get Info dialog in the World Editor has been expanded to include controller and texture mapping settings that used to be shown in separate windows. The Get Info dialog now has multiple tabs, and the Controller tab is always present. Geometries now have tabs for geometry building flags, rendering flags, collision properties, and texturing settings. * There are now a few additional tabs in the Get Info dialog: General, Properties, and Connectors. The General settings pane allows you to set the name of any node and, for certain types of node, to specify whether it is initially disabled. The Properties pane lets you assign any kind of properties defined by a game to a node. (More about properties below.) The Connectors pane lets you define a list of connectors that can be linked to other nodes. (Connectors are described in the next item.) * Implemented a general node connecting interface in the World Editor. There is now a "Select and Connect" tool that causes available connection sites for a node to be displayed along with connectors that point to their targets. Several types of nodes have built-in connectors that can be linked to other nodes for specific purposes, and any node can have an unlimited number of custom connectors defined for it in the Connectors pane of the Get Info dialog. Connectors are identified by a 32-bit (four character) identifier. The built-in connectors are as follows: ** A zone has two connectors: one called AMBT that connects to an ambient space, and one called FOG that connects to a fog space. ** A portal has one connector called ZONE that connects to the portal's destination zone. ** A light has one connector called SHAD that connects to a shadow space. ** A trigger has one connector called TARG that can connect to any type of node. * To specify the target of a connector, click on the Select and Connect tool (or press 5) and then select a node for which you want to set an outgoing connection (but don't select the target yet). The available connectors will appear in little boxes containing their identifiers with icons showing what types of node they can be connected to. Click in a box to select a connector, and it will change color and get a thicker outline to indicate that it's selected. Then select the target node and choose Connect Node from the Node menu (or just hit Ctrl-L). You will see a yellowish line with arrowheads pointing from the connector to the center of its target. Connectors from multiple nodes (one connector each) can be selected by using the shift key. This can be useful if, for instance, you want to connect a bunch of zones to the same fog space. (You don't have to use the shift when selecting the zones, but just when selecting the connectors in the zones.) A connector can be broken by selecting it and choosing Unconnect Node from the Node menu (or hitting Ctrl-U). * There is now a connection marker that can be used simply as a container that holds connectors. This could be useful in cases such as when multiple triggers need to activate the same script. (This replaces the collection node mentioned in the notes for build 112.) * Added a reference marker node type that lets you reference an external world resource from within a scene graph. In the world editor, the reference marker is represented by a world icon with crosshairs running through it. The position where the crosshairs meet determines where the origin of the external world in placed. The referenced world resource is set in the Get Info box for the reference marker. * When a world is loaded, reference markers cause external worlds to be brought in as nonpersistent nodes so that they are not saved as part of the referencing world. If the same world is referenced by multiple reference markers, then they share the same object storage; that is, they are instanced. Reference inclusion is ''not'' recursive—referenced worlds within referenced worlds will not be expanded. This avoids problems with cyclic references, etc. * There is a toggle button in the World Editor that shows or hides referenced worlds. When it's off, you just see the reference markers. When it's on, you see the reference markers and the instances of the worlds that they reference. Moving or rotating the reference marker also affects the included world (because the included world is attached to the marker as a subtree). You cannot select any part of a referenced world because it doesn't really belong to the world that references it. Changes to referenced worlds must be made in the original file. If you change a referenced world while another world referencing it is also open, you can toggle the referenced world button off and back on again to see the updated version. * Implemented a general scripting architecture. The scripting system is not based on a scripting language, but is instead designed to execute a tree of operations called methods that can be assembled graphically in the World Editor. A script is assigned to a node by selecting the script controller in the Get Info dialog and then opening the script editor. Details about the script editor can be found on the [[Graphical Scripting Language]] page. * A script is normally executed through the activation of the script controller. It is also possible to make a script run immediately upon loading a world by checking a box in the Controller pane of the Get Info dialog. * By default, a script runs on all machines in a multiplayer game. It can be made to run only on the server, but then each of the script methods must somehow communicate any actions that need to take place on the client machines. This is normally done by sending controller messages from within custom script methods. * This is only the first version of the scripting system, and additional features will be added in future releases. In particular, conditional execution is script methods is not present, but will be added later. The current scripting system is very extensible because it's possible for the Game Module to define custom script methods, and these appear in the script editor. There is also a new mechanism for accessing controller functionality from within scripts by calling "function" objects, described next. * Added the ability for controllers to define subclasses of the <code>Function</code> class that expose various kinds of functionality that can be accessed from a script. There is a script method named "Call Function" that lets you select a function belonging to the controller attached to the method's target node. When you select a function, its configurable settings appear, and these act as the function's parameters. * Trigger node functionality has been enhanced. A trigger will now call its target controller's <code>Activate()</code> function whenever it transitions from the unactivated to activated state, and it will call its target controller's <code>Deactivate()</code> function whenever it transitions from the activated to unactivated state. A trigger can be set to automatically disable itself that first time it is activated, and in this case the <code>Deactivate()</code> call is not made. It's also possible to specify that a trigger is to be continuously activated as long as an eligible node intersects it, in which case the <code>Activate()</code> function is called every frame until the trigger is unactivated. * The Game Module can now define <code>Property</code> subclasses for whatever reason it needs to, and these can be exposed in the World Editor under the Properties tab of the Get Info dialog. * Finished implementing the <code>Configurable</code> base class. Different types of classes that are capable of displaying a configuration interface in the World Editor are subclassed from <code>Configurable</code>. Currently, the classes that have the configurable functionality are <code>Controller, Property, Method,</code> and <code>Function</code>. A configurable class specifies that it has one or more ''settings'' that need to be presented to the user at the appropriate time. There are several types of built-in settings: a boolean (check box) setting, integer/float (slider) settings, a text box, a popup menu, a color box, and a resource picker. New types of settings can be defined by the Game Module. * Added a movie controller that plays a QuickTime movie into any of the texture map material attributes. The <code>MovieController</code> class exposes two <code>Function</code> objects that can be used to play or stop movies from a script. A movie can also be played immediately upon loading a level or it can be played in response to a trigger activating the movie controller. * Added the <code>MovieElement</code> class that plays a QuickTime movie into an interface element. * The <code>Source</code> node has been updated with more complete functionality. Sound sources can now be placed in a world in a dormant state until they are explicitly played. There are two script methods, "Play Sound Source" and "Stop Sound Source" that play/stop a source node connected to the script's owning node. * Implemented a particle rendering technique that I call "sprite quads". This allows the sprite rendering hardware to be used to render an arbitrarily-oriented quad inside a screen-aligned point sprite. The benefit is that only one quarter of the vertex information needs to be transferred to the GPU for each quad. The expense is a small increase in fill, but this can be alpha-tested to avoid the final write. This technique was used with excellent results in a PS3 technology demo, and it works very well on Nvidia hardware. Unfortunately, the OpenGL spec requires that point sprites be entirely clipped if their centers go outside the view frustum. Nvidia has ignored this requirement (which is good), but ATI adheres to it by clipping point sprites in software (which also means they perform the vertex transform in software). This could make the whole sprite quad technique somewhat useless unless an OpenGL extension can be agreed upon to allow point sprites to be clipped as if they were quads. Of course, with the forthcoming geometry shaders, none of this will really matter. * Made several improvements to the joystick support in the Input Manager. More to come, including direct access to the Xbox 360 controller data. * Added the <code>SetMousePosition()</code> function to the Interface Manager. * Added a "world time multiplier" to the Time Manager that can be used to control the rate at which time passes in a game world. The multiplier is initially 1.0 and can be changed by calling the <code>TimeMgr::SetWorldTimeMultiplier()</code> function. The functions <code>TimeMgr::GetDeltaTime()</code> and <code>TimeMgr::GetFloatDeltaTime()</code> now return world time, which is the actual time that has passed multiplied by the world time multiplier. You can still get the unaltered actual time that has passed using the new <code>TimeMgr::GetSystemDeltaTime()</code> and T<code>imeMgr::GetSystemFloatDeltaTime()</code> functions. * Removed the <code>GeometryController</code> class. A controller which can be assigned to a geometry node no longer needs to be subclassed from <code>GeometryController</code>. * Settings for the fluid controller and cloth controller can now be accessed in the Controller pane of the Get Info dialog. * Added the <code>MoveSubtree()</code> and <code>Descendant()</code> functions to the <code>Tree</code> class. * Added the Strong AA check box to the Font Generator tool. This causes partially filled pixels to be weighted more heavily so that small font sizes can be made more clear. * If the <code>GL_EXT_timer_query</code> extension is available (currently, only on Nvidia hardware), then the frame rate window will now display a second graph that shows the amount of time spent rendering on the GPU. This shows the actual GPU load regardless of whether vertical sync is on or off, and it can highlight time spikes that happen only on the CPU. 7042e48d710fb22c6857d6e63c3d2a193d81752a Release Notes for Build 117 0 22 24 2023-07-15T09:32:13Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' March 20, 2006 * The standard appearance of the graphical user interface has been overhauled. The new design doesn't have so much color in it and uses the more familiar dark-on-light shading for text. The fonts have been updated to look nicer and be more readable. * Added the <code>$backgroundColor, $windowColor,</code> and <code>$hiliteColor</code> permanent variables to the Interface Manager. These can be changed in the <code>Data/CFG/V..." wikitext text/x-wiki __NOTOC__ '''Release date:''' March 20, 2006 * The standard appearance of the graphical user interface has been overhauled. The new design doesn't have so much color in it and uses the more familiar dark-on-light shading for text. The fonts have been updated to look nicer and be more readable. * Added the <code>$backgroundColor, $windowColor,</code> and <code>$hiliteColor</code> permanent variables to the Interface Manager. These can be changed in the <code>Data/CFG/Variables.cfg</code> file to alter the default appearance of the user interface. Each variable is interpreted as a 6-digit RGB hexcode with 8-bits per component: RRGGBB. * Added window resizing to the Interface Manager. The World Editor and Model Viewer windows can now be resized by dragging the little widget in the bottom-right corner. As a window is being resized, it receives calls to the virtual <code>SetWindowSize()</code> function so that a window can reposition its contents. * Added some new functionality to the <code>EditableTextElement</code> interface class. It can now accept more text than its size allows it to display (when the <code>kEditableTextOverflow</code> flag is set), and you can now use the shift key with the left and right arrows to select text. * The standard file picker dialog now allows you to navigate into subdirectories. The popup menu at the top of the dialog contains each directory in the path leading back up to the original directory for which the file picker was created. Clicking the button with the 'go up a directory' icon or hitting Ctrl-Up-Arrow navigates to the enclosing directory. * Added a check box to the Save As dialog in the World Editor that lets you strip out the editor data when saving a world. Stripping out the editor data removes information about things like viewport configurations, material names and previews, show/hide state, etc. When the strip box is checked, it only applies to that one save—subsequent saves will continue to write the editor data. The intent is that users will save different copies of final worlds that are stripped down for gameplay. * Added the Connect to Root Zone item to the Node menu in the World Editor. After selecting a connector, this item connects it to the infinite root zone of the scene. * Added the ability to set the number of skybox subdivisions in the World Settings dialog. * Added a "Developer Panel" window that provides an interface for generating texture resources for lights, environment maps, etc., and also provides an interface for turning some rendering diagnostics on and off. The developer panel can be opened by selecting Developer Panel from the Tools menu or by typing dev in the console. This replaces the gentex command that was previously used to generate textures. * Added a <code>Preprocess()</code> function to the <code>Method</code> class. This allows a method to perform precaching if it wants to. * Made some miscellaneous optimizations in the light and shadow culling code. * Fixed a problem that could cause a recursive chain of multiple remote portals to render incorrectly. * Fixed a problem that would cause a vertex program error if refraction and fog were used in the same material. * Worked around a driver bug that was causing the glow shader to drop into a software path on some GeForce FX GPUs. Glow should now render at full speed on all Nvidia hardware. a73c00be1f232073c1d1d12b77c1d2ab26cedd2e Release Notes for Build 118 0 23 25 2023-07-15T09:32:41Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' March 28, 2006 * Added a validation function to the <code>PropertyRegistration</code> class so that property subclasses could identify which types of nodes they are supposed to be used with. This works in the same way that the validation function works for controllers. The validation function is only used to determine which available properties to list for a particular node in the Get Info dialog. * Fixed a problem in the Collada Importer..." wikitext text/x-wiki __NOTOC__ '''Release date:''' March 28, 2006 * Added a validation function to the <code>PropertyRegistration</code> class so that property subclasses could identify which types of nodes they are supposed to be used with. This works in the same way that the validation function works for controllers. The validation function is only used to determine which available properties to list for a particular node in the Get Info dialog. * Fixed a problem in the Collada Importer tool that would cause polygons having more than four vertices to import incorrectly. * Fixed a problem in the Texture Importer tool that was causing manually created cube maps to import incorrectly. 31287cd84e1d37f1ab7454d1fbd586329636b295 Release Notes for Build 119 0 24 26 2023-07-15T09:33:36Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' April 18, 2006 * For fog spaces, you can now select whether to use a constant density or a density that increases linearly with distance from the boundary plane. The linear density function is slightly more expensive (one additional fragment program instruction on NV40+, a surprise considering the extra complexity), but it can look much better when the camera is near the fog boundary. * Fog spaces now use the occlusion system to cull obje..." wikitext text/x-wiki __NOTOC__ '''Release date:''' April 18, 2006 * For fog spaces, you can now select whether to use a constant density or a density that increases linearly with distance from the boundary plane. The linear density function is slightly more expensive (one additional fragment program instruction on NV40+, a surprise considering the extra complexity), but it can look much better when the camera is near the fog boundary. * Fog spaces now use the occlusion system to cull objects that are completely fogged. In all cases, 1-2 planes are used to cull objects, but the exact configuration depends on the camera location with respect to the fog boundary plane and the density function. In cases where you know that no objects will ever be completely fogged, you can disable distance occlusion for a fog space in the Get Info dialog to save a little CPU processing time that would ordinarily be spent looking for objects to cull. The culling distance varies smoothly with the fog color. For bright fog, the culling distance is set to be the point at which the fog fraction is 1/32, and for dark fog, the distance corresponds to a fog fraction of 1/256. This was done because the human eye can't distinguish between close bright shades as well as close dark shades. * If the camera is outside a fog space, then the rectangular boundary plane must be visible in order for the fog to be rendered. This is different from previous versions—before, fog would render if the zone containing it (or connected to it) was visible. Existing fog planes may have to be resized to cover the entire area that they affect. It's okay for a fog plane to extend outside its owning zone. * Added a "confined light" optimization that avoids recalculating light regions for a light source that moves but is known to stay confined within a certain radius. This is currently used for the torches in the demo level—the <code>TorchController</code> class makes the torch light wiggle around a little bit as part of the flickering effect. Previously, the light regions would have to be recalculated every frame, and this involved a lot of portal clipping. Now, slightly larger light regions that are valid as long as the light stays inside its confinement sphere. This saves a significant amount of CPU processing time. * Support for vertex buffer objects (VBOs) has been completed in the Graphics Manager. After several iterations, a good design for using VBOs without requiring them was converged upon. All geometry objects will now store static vertex and index data in VBOs to increase performance. In future releases, more types of objects will take advantage of VBOs. * Added an opacity map attribute to the material system. This is only used in conjunction with the refraction attribute and controls how opaque a surface is at each texel. Values in the opacity map are used as a linear interpolation parameter between the diffuse reflection term and the refraction term. White means completely opaque (100% diffuse term), and black means completely transparent (100% refraction term). Opacity can either be stored in its own texture map, or it can be stored in the alpha channel of the diffuse map, normal map, gloss map, or emission map. * The gloss map attribute is now applied to the reflection attribute. Gloss can also come from the alpha channel of the diffuse map, normal map, emission map, or opacity map. * The Collada importer can now handle skinned meshes placed anywhere in the node hierarchy, whereas before, a skinned mesh was expected to be at the top level. * The Collada importer will now strip out dead nodes. A "dead node" is a node that doesn't instance any object, doesn't have any subnodes, and isn't a bone. Collada exporters tend to write a bunch of these out because they're used to represent various items in the art package, but they don't carry any useful information. Importing them into the engine just wastes space and time. * Made multiple improvements to the Time Manager so that it reports time values that are as accurate as possible. * The Properties tab will now show up in the World Settings dialog so that properties can be assigned to the root zone. This allows games to store custom properties on the root zone for global level settings. * Added a loop count box to the Play Ambient Sound script method. * Added a preview box to the file picker for the Texture Viewer tool. * Fixed a typo introduced in build 117 that causes rendering problems when multiple remote portals were visible at once that rendered to the same buffer. * Made lots of improvements to the Mac project file. There are now two configurations named "Debug" and "Release". Precompiled headers are used in a better way now, so build times are much faster. 94d3fb08163d0d7890994afb89b632830958e04c Release Notes for Build 120 0 25 27 2023-07-15T09:34:11Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' April 20, 2006 * Implemented the rectangular select tool in the World Editor. It respects the selection mask, and the shift key can be used to add to an existing selection. Because of the different kinds of bounding volumes that some things use, you may select a little more than you expect for a particular dragged out rectangle. * Fixed a bug introduced in build 119 that would cause geometries not to update properly in the World Editor...." wikitext text/x-wiki __NOTOC__ '''Release date:''' April 20, 2006 * Implemented the rectangular select tool in the World Editor. It respects the selection mask, and the shift key can be used to add to an existing selection. Because of the different kinds of bounding volumes that some things use, you may select a little more than you expect for a particular dragged out rectangle. * Fixed a bug introduced in build 119 that would cause geometries not to update properly in the World Editor. * Fixed a bug in the Texture Viewer tool that was introduced with the new preview box that would cause a crash if a texture was double-clicked to be opened in the file picker dialog. d25442ecdffda7616c5460f26ae5fefdc631a82b Release Notes for Build 121 0 26 28 2023-07-15T09:34:41Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' April 24, 2006 * Added a new procedural fire effect. This replaces the old effect that's been in the engine and is vastly superior in multiple respects. The <code>FireEffect</code> class is now in the engine core and is accessible in the World Editor. The fire effect can be placed in a world by using the tool in the markers/triggers/effects panel. The Get Info dialog for the fire effect contains settings for the radius and height of the fir..." wikitext text/x-wiki __NOTOC__ '''Release date:''' April 24, 2006 * Added a new procedural fire effect. This replaces the old effect that's been in the engine and is vastly superior in multiple respects. The <code>FireEffect</code> class is now in the engine core and is accessible in the World Editor. The fire effect can be placed in a world by using the tool in the markers/triggers/effects panel. The Get Info dialog for the fire effect contains settings for the radius and height of the fire, the texture to use, and a couple animation parameters. * A single fire effect is rendered as a camera-facing quad that is constrained to rotate about its local ''z''-axis. Its animation is controlled by an intensity value and a turbulence speed value. The default texture, <code>Flame.tex</code>, can be used to simulate everything between a flickering candle and a roaring torch. When designing a new texture for use with the fire effect, be sure to leave empty space at the top and on the left/right sides so that flames aren't cut off. The alpha channel is used to control transparency. * The texture pickers in the material manager and info dialogs now show preview images. * Fixed a bug that would cause the file save dialog to crash if there was no selection in the file list. 695c3c5dadaa045c55188b3105cb59d1449e6615 Release Notes for Build 122 0 27 29 2023-07-15T09:35:24Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' May 24, 2006 * '''IMPORTANT:''' In order to use the save game functionality in this release, you must update any world that will be saved as a save game to a slightly newer format. To update a world, simply open the world in the World Editor and then immediately save it. Although no problems are anticipated, it's highly recommended that you backup your WLD resources before running this build. * Implemented delta save files for saved games..." wikitext text/x-wiki __NOTOC__ '''Release date:''' May 24, 2006 * '''IMPORTANT:''' In order to use the save game functionality in this release, you must update any world that will be saved as a save game to a slightly newer format. To update a world, simply open the world in the World Editor and then immediately save it. Although no problems are anticipated, it's highly recommended that you backup your WLD resources before running this build. * Implemented delta save files for saved games. Saved games get stored in the <code>Save/sav/</code> directory. (The Save directory is the root of a new resource catalog.) Games are saved and restored using the <code>WorldMgr::SaveDeltaWorld()</code> and <code>WorldMgr::RestoreDeltaWorld()</code> functions. A save game file stores the entire node hierarchy and all controller information, but it only stores the objects that it actually needs to store. Any objects that exist in the original world and haven't been modified are not saved in the delta file. Since nearly all geometrical information is stored in the shared objects, this makes saved games extremely small compared to the original world. (In the case of the demo world, a saved game is only 1.5% the size of the original world.) Any new objects introduced since a world was loaded and any deleted objects are automatically handled. * If a saved game is restored while the original world for which it was saved is still loaded, then a special fast path is taken through which any original, unmodified objects already in memory are reused. Then only missing or modified objects are reloaded from the original world resource. Since materials are stored in objects, this also minimizes texture reloading. * If the game code modifies an object directly, it must call the <code>Object::SetModifiedFlag()</code> function to ensure that the object is correctly saved in a delta file. If this function is not called appropriately, a modified object may be restored to its original state when a saved game is reloaded. Note that this function only needs to be called for changes to an <code>Object</code> class, which are relatively rare. Modifications to a Node class do not require a similar call to be made because all node data is always saved. * Added QuickSave and QuickLoad input actions to the sample game. These are initially bound to the F6 and F9 keys, respectively. There is also a new Save Current Game item in the main menu that lets you save a named file. The Load Saved Game item in the main menu is now functional. * Scripts are now fully re-entrant without limitation. By default, a script has re-entrancy disabled, but it can be enabled by checking the "Allow multiple instances to run simultaneously" box in the Controller pane of the Get Info dialog. In order to support re-entrancy, all script methods and controller functions must be able to replicate themselves, meaning they must implement a copy constructor and override the <code>Replicate</code> function. * Implemented full-scene motion blur as a postprocess effect. Motion blur affects everything uniformly and provides the same "cinematic" level of quality advertised by another engine that shall go unnamed. In particular, motion blur is determined by the combination of camera motion, object motion, and also vertex motion for things like skinned characters and cloth. * In this release, motion blur requires FBO support. A p-buffer fallback will be implemented in a minor update. * Added a geometry flag to the Get Info dialog to disable motion blur. This can be useful for things like geometry covering a remote portal so that double blurring of the remote image doesn't occur. * Added new check boxes for enabling or disabling postprocessing effects in the Graphics Options dialog. * Added the <code>StopMotion</code> function to the <code>Node</code>. This function is used to signal that a node previously in motion has stopped and ensures that the stored transforms used for determining motion blur are reset. This function is necessary because stopped nodes usually aren't being invalidated, so they also aren't being updated any more, and that's where previous transforms are saved to calculate motion blur. See the documentation at [[http://c4engine.com/docs/WorldMgr/Node_StopMotion.html <code>Node::StopMotion</code>]]. * Added flags to the <code>MaterialObject</code> class that let you specify two-sidedness and alpha testing on a per-material basis (whereas before, it could only be done per-geometry). The material editor has been updated to support these flags—they can be found in the General pane. * Added slots for a secondary texture map and a secondary normal map in the material editor. When two normal maps are specified, they always add in the mathematically correct way as if their original height maps had been added together. Parallax mapping is automatically disabled for a material when there are two normal maps. * You can now choose an input texture coordinate set for each texture in a material. * Added support for animated texture coordinates. Each texture coordinate set can be animated using the settings under the Texcoords panel in the material editor. All texcoord animation is based on a 120 second period, so individual coordinate velocities must be set so that an integer number of complete cycles have occurred every 120 seconds. (The editor enforces this.) Since the coordinate velocities are quantized, not all animation directions are available at slow speeds. At the slowest possible speed (making one cycle every 120 seconds), the available directions are multiples of 45 degrees. * The reflection attribute now uses the Schlick approximation for a Fresnel factor. The normal incidence reflectivity is still controlled by the existing slider under the Buffers panel in the material editor. (Water has a very low normal incidence reflectivity, so a value of 1 or 2 would be appropriate.) * Added a flag for remote portals that stops skyboxes from being rendered through them. This is useful if you know that no part of the skybox will be visible through the portal (e.g., when used for underwater refraction). * Added a flag to the fluid controller that forces vertices to remain in a plane. When this flag is specified, only the normals and tangents are animated. This is necessary to prevent gaps in a refraction buffer rendered for the fluid. This flag can be set in the Get Info dialog under the Controller pane. * Added a buffer exclusion mask to fog spaces. These will stop fog from being applied in the primary, reflection, or refraction render buffers. These are accessible in the Get Info dialog. * The fire effect and flare effect tools in the World Editor now let you drag out their sizes. The fire effect is cylindrical, and the flare effect is spherical. * Implemented the <code>FlickerController class</code> in the game module. This causes a point light source to change in intensity and move back and forth quickly like flickering fire. This controller can be assigned to a light and configured in the Get Info dialog. * Made a lot of improvements to the Model Viewer tool. The window now displays information about the model such as node count, vertex count, and face count. The mouse wheel will now zoom in and out. The tools can be selected with hotkeys. (The pan, zoom, and free camera tools use the same keys as the World Editor: 6, 7, and 9. The orbit and light tools use 1 and 2.) You can now select an environment in which the model is placed by choosing Select Environment from the Model menu. Any world saved in the <code>Data/wld/ModelViewer directory</code> can be used as the environment. If you make a new environment, it should not have any subzones in it (just the root zone). The model is always placed at the origin. * Reimplemented normalization cube maps for GeForceFX processors. (This was implemented a long time ago, but was removed somewhere along the way during shader system revisions.) In fill-limited test scenes, this now provides about a 25% speedup. This optimization is only used on GeForceFX-class hardware because all other supported hardware performs normalizations faster using ALU instructions. * Added a lower-quality texturing mode that can provide a quality/performance trade-off. If the "Use high-resolution textures" box is unchecked in the Graphics Options dialog, then all textures with mipmaps are reduced to half resolution. * Fixed a problem that would cause entities using a <code>SkinController</code> not to get cloned correctly (the controller wasn't getting cloned for any skinned meshes). * Fixed a bug that would cause QuickTime movies to crash on MacOS X. * Added a message box that appears if the engine is run on sub-minimal graphics hardware. 4026ff74fe43270f6173d1ef6dcc7bdcdd0790b4 Release Notes for Build 123 0 28 30 2023-07-15T09:35:57Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' June 6, 2006 * A pbuffer fallback has been implemented on the Windows platform, and it is used if the <code>GL_EXT_packed_depth_stencil</code> extension is not present. An equivalent fallback has not been implemented for the Mac platform because it does not support pbuffers that can share a rendering context when the pixel format is identical. * Motion blur can now be rendered on all supported hardware running on the Windows platform. *..." wikitext text/x-wiki __NOTOC__ '''Release date:''' June 6, 2006 * A pbuffer fallback has been implemented on the Windows platform, and it is used if the <code>GL_EXT_packed_depth_stencil</code> extension is not present. An equivalent fallback has not been implemented for the Mac platform because it does not support pbuffers that can share a rendering context when the pixel format is identical. * Motion blur can now be rendered on all supported hardware running on the Windows platform. * Reflection and refraction images are now rendered directly to texture buffers (i.e., there is no copy) on the Windows platform. In some cases, this can produce a 5-10% speed increase. * The material editor now has settings for texcoord scale and offset under the Texcoord pane. There are separate settings for the ''s'' and ''t'' directions. Scale and offset are applied before texcoord animation. * Dual diffuse texture maps are now supported. The material editor has a new popup menu at the bottom of the General pane that lets you select how the two textures are combined. The current options are add, average, multiply (modulate), blend with vertex alpha (for future use), or blend with the alpha or inverse alpha of either texture map. The two textures can also use independent texcoord transforms and animations. * Right mouse button events are now sent through to interface elements using the event types <code>kEventRightMouseDown</code> and <code>kEventRightMouseUp</code>. * The Tool Manager now maintains a list of scene export tools. You can register a scene export tool by creating a subclass of the SceneExportTool class and calling the <code>ToolMgr::RegisterSceneExportTool()</code> function. When one or more export tools are registered, the Export Scene command becomes available in the World menu inside the World Editor. a4a3c1f986754320a96c7be036217034a17ece6a Release Notes for Build 124 0 29 31 2023-07-15T09:36:21Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' June 25, 2006 * Implemented support for version 1.4 of the Collada format. The Collada Importer tool can now read both versions 1.3 and 1.4, and everything that was supported in version 1.3 is now supported in version 1.4. * Introduced frame time normalization in the World Manager. This is currently applied to velocity-dependent effects like full-scene motion blur and line particles, giving them a uniform appearance at all frame rates. By..." wikitext text/x-wiki __NOTOC__ '''Release date:''' June 25, 2006 * Implemented support for version 1.4 of the Collada format. The Collada Importer tool can now read both versions 1.3 and 1.4, and everything that was supported in version 1.3 is now supported in version 1.4. * Introduced frame time normalization in the World Manager. This is currently applied to velocity-dependent effects like full-scene motion blur and line particles, giving them a uniform appearance at all frame rates. By default, the effects are adjusted so that they appear as if the game was running at 60 frames per second (i.e., 16.666 milliseconds between frames). The default frame time can be changed by calling the <code>WorldMgr::SetDefaultVelocityNormalizationTime()</code> function and passing in a new normalization time in milliseconds. When a world is loaded or created, it grabs this default time, but you can also set a per-world normalization time using the <code>World::SetVelocityNormalizationTime()</code> function. Longer times make the effects more prominent, and shorter times make the effects more subtle. * Added a new flag to remote portals that allows light to pass through them as if they were direct portals. This can be used to let light pass through windows that use remote portals to get bumpy transparency. If this flag is turned on for a remote portal that isn't a simple "pass-through" portal, then the results are undefined. That is, it won't work for mirrors and portals that look at a remote location. * Implemented significantly better shadow-casting set determination in the World Manager. The engine will now render far fewer shadow volumes, saving a lot of time that was previously spent both calculating and rendering shadows that couldn't be seen. * The <code>Clonable</code> class has been renamed to <code>EntityRegistration</code> to be consistent with the other types of objects that are registered. * Updated the primitive geometries where necessary so that the natural texture coordinates always form right-handed tangent space. * The World Editor now initially disables shadows for the planar primitive geometries since they don't form closed meshes by themselves. * Added an input action binding to the game module that lets you switch between the first-person camera and the chase camera. This is disabled in multiplayer mode so that you can't cheat by looking around corners. * Added a specialization to the <code>String</code> class template for arbitrary-length strings. Passing 0 as the template parameter causes this specialization to be used. This is the default value, so declaring a string as String<> will grab the class that supports arbitrary lengths. Note that it is less efficient to use this class (but more convenient), so the sized strings should be used when possible and/or practical. * Fixed a problem in the World Editor that would cause hidden objects to be selected by the box select tool. * Fixed a problem in the game code that would fail to catch a <code>ResourceException</code> if you tried to do a quick load, but there was no quick save file. 2f22b72dec65047fe27ce9622f1ff601320ba75b Release Notes for Build 125 0 30 32 2023-07-15T09:36:50Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' June 30, 2006 * Implemented an entity placement tool pane in the World Editor. An entity is placed in the world by selecting an entity type from the list, clicking on the entity's position, and dragging to rotate it into the desired orientation. This places an actual entity node into the scene, but it has no model hierarchy until the world is loaded for gameplay. An entity may be initially disabled in the Get Info dialog, in which case it i..." wikitext text/x-wiki __NOTOC__ '''Release date:''' June 30, 2006 * Implemented an entity placement tool pane in the World Editor. An entity is placed in the world by selecting an entity type from the list, clicking on the entity's position, and dragging to rotate it into the desired orientation. This places an actual entity node into the scene, but it has no model hierarchy until the world is loaded for gameplay. An entity may be initially disabled in the Get Info dialog, in which case it is not rendered until it is explicitly enabled. * The <code>EntityRegistration</code> class now accepts a controller type parameter that specifies the type of controller to automatically assign to an entity when it is placed in a world using the World Editor. The Skeleton game code has been modified to demonstrate how to register the entity for the green bouncing balls and automatically assign the <code>BallController</code> to them. Also, all of the collectable items in the demo game code have been upgraded to use the new entity placement system with automatic assignment of the <code>Collectable</code> controller. * Updated the Collada 1.4 import tool to handle some additional variations of skinning data. * Added simple mouse smoothing code. Mouse smoothing can be turned on and off in the Control Settings dialog. The default setting is on. * Implemented some experimental frame time filtering code. This should help smooth jitters out when frame deltas change by a large amount. * Added some code that should make monitor frequency selection more reliable under Windows in full-screen mode. * The menu bar will now always appear if the console window is opened without a world being loaded. * Fixed a problem in the game code that would cause a crash if the camera view was changed in spectator mode. 43b55177489639b52d5a9a7c38bb1a2e54540f18 Release Notes for Build 126 0 31 33 2023-07-15T09:37:30Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' August 31, 2006 * '''IMPORTANT:''' In the unlikely case that you have world or model resources that have not been saved in build 113 or later, you need to open them and save them in build 125 before opening them in build 126. * '''IMPORTANT:''' Because of some format changes in this build, it's recommended that you open and save all worlds and models to update your resources. In most cases, resources will shrink in size slightly. * '''I..." wikitext text/x-wiki __NOTOC__ '''Release date:''' August 31, 2006 * '''IMPORTANT:''' In the unlikely case that you have world or model resources that have not been saved in build 113 or later, you need to open them and save them in build 125 before opening them in build 126. * '''IMPORTANT:''' Because of some format changes in this build, it's recommended that you open and save all worlds and models to update your resources. In most cases, resources will shrink in size slightly. * '''IMPORTANT:''' Changes in this build have largely removed the need for the concept of "group space" in the engine. Plans are to remove group space functionality in the next build, so please update any geometries using group space by merging all such geometries in each group together into a single object (more below). * Implemented support for multiple materials on a single renderable object. The <code>Renderable</code> class now supports multiple ''render segments'' represented by the <code>RenderSegment</code> class. Each segment corresponds to a separate material and has its own material attributes and shading data. The first segment is built into the <code>Renderable</code> class, and additional segments can be attached by a higher-level object. * The higher-level object normally attaching additional render segments is the <code>Geometry</code> class, which now supports multiple materials. The <code>GetMaterialObject()</code> and <code>SetMaterialObject()</code> functions now take a material index to identify a material slot. The number of material slots for a geometry is always at least 1 and can be set using the <code>SetMaterialCount()</code> function. The granularity at which multiple materials can be applied is based on the division of a geometry into surfaces. Surfaces are groups of polygons that are isolated with respect to normal smoothing, bump mapping, etc. These have been supported by the engine for some time, but now each surface can designate a separate material. When a geometry is built, all sets of surfaces sharing a common material are combined to form a single segment, so the number of render segments is always less than or equal to the number of surfaces. * The Collada Importer tool will now apply multiple materials to meshes that have multiple surfaces referencing different materials. Each occurrence of a <code><polygons>, <polylist>,</code> or <code><triangles></code> element within a <code><mesh></code> element generates a separate surface to which a distinct material may be applied. * Changed the behavior of the Merge Geometry command in the World Editor. Previously, this would merge the selected geometries and apply the current material to the result. Now, it generates a single geometry that has all of the original materials applied to it. The number of surfaces in the resulting geometry is the sum of the numbers of surfaces in the input geometries. If surfaces of multiple input geometries use the same material, then they are combined into the same segment of the resulting geometry, but the surfaces remain separate. * Changed the behavior of the CSG operations in the World Editor so that they now always produce a single geometry with multiple materials. All surviving surfaces of a CSG operation between two geometries are combined into a single geometry, and only the materials used by the surviving surfaces are applied to the new geometry. * CSG operations now generate as many LODs as the maximum number possessed by the two input geometries, whereas previously, only the minimum number of LODs were generated. This is useful if you do something like subtract a two-LOD cylinder from a single-LOD box and still want two LODs in the result. * Completed the in-game interface panel system. Under the markers/triggers/effects panel in the World Editor, there is a new effect called "Panel Effect" that lets you draw a rectangular interface panel. This effect automatically has a panel controller assigned to it that can be configured under the Controller pane in the Get Info dialog. There are two sliders here that control the resolution of the interface panel—these are independent of the size of the panel effect in the editor viewport. Clicking on the Edit Panel button opens the Panel Editor window where the contents of the interface can be designed. * The Panel Editor window contains tools similar to those that would typically be found in a 2D drawing application. In this build, there are two types of items that can be placed in an interface panel: images and text. A future build will also include a viewport item that can display a rendered image from another camera in the world. An image or text item is placed in the interface by selecting one of the drawing tools in the upper-left part of the window and dragging out a rectangle. The texture applied to an image item is the one selected on the left side of the window. The texture palette displays all of the textures in the <code>Data/tex/panels/</code> directory (but any texture can be applied to an image by changing it after it's drawn). * When a single item is selected in the Panel Editor, its properties can be edited on the right side of the window. The item identifier is a four-character code that can be used to identify different items from a script—they do not need to be unique, so it's possible to identify a group of items using the same value. The Disabled and Hidden check boxes determine whether an item is initially clickable or initially hidden, respectively. * A panel item can be made interactive by assigned a script to it. To do so, select the item and click the Edit Script button at the bottom of the window. The script will run each time the panel item is clicked. Note that the Interaction property must be assigned to a panel in order for it to receive interaction events (see below). * Panel items can be animated by assigning one or more ''mutators'' to them. The popup menu on the right side of the window contains the available mutators for a selected panel item, and the list box next to it displays the mutators that are currently assigned to the item. A new mutator is added to a panel item by selecting it from the menu and clicking the Add button. Like a panel item, each mutator also has a four-character identifier that can be used to identify it from a script. * The <code>PanelController</code> class exposes a number of functions that can be called from a script. Each function takes a panel item identifier as a parameter that determines which items are affected. A blank identifier is a wildcard and matches all panel items. For functions that operate on mutators, a separate mutator identifier is also specified, and a blank identifier is a wildcard that matches all mutators. * Implemented an interaction event system that's used to communicate user interaction information to the controllers of interactive objects in a world. Currently, any geometry node or panel effect node can be made interactive by assigning the new Interaction property to it in the Get Info window. (In particular, this property must be assigned to a panel effect before anything in the panel can be clicked.) * Interactions are reported through the <code>Interactor</code> class. An application can define subclasses of the <code>Interactor</code> class and add them to a world in order to detect interactions between a given line segment and any interactive nodes in the world. When the line segment probe first hits an interactive node, a <code>kInteractionEventEngage</code> event is sent to the <code>Interactor</code> class. As long as the probe remains in contact with the interactive node, the <code>Interactor</code> class continues receiving <code>kInteractionEventTrack</code> events. When the probe later misses the interactive node, the <code>Interactor</code> class receives the <code>kInteractionEventDisengage</code> event. The application-defined subclass can handle these in any manner necessary. * Controllers now have a <code>HandleInteractionEvent</code> function for handling interaction events. Normally, a subclass of <code>Interactor</code> will pass interaction events to the controller attached to the interactive node that has been engaged. There are two additional events, <code>kInteractionEventActivate</code> and <code>kInteractionEventDeactivate</code>, that can be sent to a controller when the user explicitly generates some kind of input indicating that they want to activate the node that they're currently passively engaged to. This needs to be handled by the Application Module. * Implemented an associative key-value container called <code>Map</code>. It works like the <code>List</code> class in that there is also a <code>MapElement</code> class from which objects stored in a map need to be derived and the map owns its members. As with the list container, there is no memory allocation done when an object is inserted into a map—all of the linking pointers are part of the object itself. This also has the advantage that destroying an object automatically removes it from any map it is a member of. * The <code>Map</code> class uses an AVL tree implementation to maintain a balanced binary tree. This provides 1.44×O(log ''n'') time searches in the worst possible case, where n is the number of objects in the map. (A red-black tree, used by most STL implementations, will take 2×O(log ''n'') time in the worst case.) * Added the <code>Terminate</code> function to the <code>ScriptController</code> class. This terminates all scripts currently running on the controller. * Added a flag to fog spaces that causes their boundary planes to become collision barriers for cameras. * Added a small feature to the <code>MarkingEffect</code> class that causes a marking to exist for exactly one frame. This is useful if you're using a marking for something like a blob shadow. To specify that a marking lives for only one frame, the <code>lifeTime</code> field of the <code>MarkingData</code> structure should be set to -1. * Added a flag to light nodes that cause them to connect to a shadow space in the referencing world when they are included through a reference marker. If the "Connect to shadow space in referencing world" box is checked in a light's Get Info dialog, then the light will look for a SHAD connector on the reference marker that caused it to be included in another world. If that connector is found and is connected to a shadow space, then the light will automatically connect to that shadow space. * Added a node flag that causes a node's object not to be shared when the node is replicated. In order for this flag to be effective, the object attached to the node must support replication. Currently, only light objects can be replicated, and a new check box has been added to the Get Info dialog that turns this flag on. This is used to force lights in referenced worlds to have independent objects so that controllers can animate them separately for things like flickering effects. * Shadow spaces can now be used with infinite lights and depth lights. As with point lights, shadows rendered for a light connected to a shadow space can be restricted by the engine to the volume bounded by the shadow space as a performance optimization. * Made significant improvements to the shadow culling code for spot lights. Some areas of the demo world got a 10-15% speed-up. * The graphics stats window (accessed by the <code>graf</code> console command) has been expanded to display a lot more information. It now shows the number of faces and the number of drawing commands used for normal rendering, shadows, and the special effect buffer. It also displays more information about the higher-level visibility statistics, such as number of objects visible, number of shadows visible, and various portal counts. * The <code>Cursor</code> class no longer holds a hotspot position. Instead, the center position of a cursor is now specified in the cursor's texture. The Texture Importer tool has been updated to allow a center point to be specified. * Connectors in the World Editor can now be set to link only to entities (in addition to all the other node types that were already there). * The Collada Importer tool will now recognize texture names with spaces in them. It will also recognize the substring "/Import/tga/" and treat anything that comes after it as the full path to a texture image so that the imported material has the correct corresponding path in the <code>Data/tex/</code> directory. * The Collada Importer tool can now apply textures for which a material attribute references a sampler instead of directly referencing the texture image. * Added a check box to the Font Generator tool that enables mipmap generation for font textures. This should be enabled for fonts that are to be used for in-game interface panels. * Added specializations to the <code><<</code> and <code>>></code> operators in the <code>Packer</code>, <code>Unpacker</code>, <code>Compressor</code>, and <code>Decompressor</code> classes to explicitly handle the <code>bool</code> type correctly. When packing into a file, a <code>bool</code> is always saved as four bytes (for alignment). When compressing into a network message, a <code>bool</code> is always written as one byte. * Made a shader optimization that reduces the number of interpolants needed when fog is used. This allows all possible combinations of shading attributes to be applied with fog. (Previously, combinations such as depth light + dual texcoords + specular + fog would overflow the available interpolants by one.) * The <code>kGeometryStaticShadowInhibit</code> flag has been renamed to <code>kGeometryDynamic</code>. This flag means a geometry might move, so the engine will not do things like cache shadow volumes for a geometry having this flag set. * Resolved a problem in which motion blur would "stick" and cause screen trashing when decals were visible. There is an unrelated motion blur problem occurring only on GeForce 7x00 hardware which is currently under investigation at Nvidia as bug #251255. ''UPDATE: A zero-cost workaround has been found, so motion blur should be rendering correctly on all graphics cards now.'' * Fixed a problem in which dual texcoords were not working if a material used a parallax map. * Fixed a problem that could cause a stopped sound source to start playing when a game is saved and restored. * Fixed a crash that would occur if the cloth controller was removed from a cloth geometry. 73f88a1736813a852732dffeedb503453e17348c Release Notes for Build 127 0 32 34 2023-07-15T09:38:03Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' September 15, 2006 * Implemented a large amount of new multiplayer functionality. The overall system is a work in progress and will be completed in build 128. The primary enhancement in this release is a new message journal that stores certain controller messages. The journal is sent to client machines when they join a game in order to update the state of various controllers before the current world is displayed. When a client machine recei..." wikitext text/x-wiki __NOTOC__ '''Release date:''' September 15, 2006 * Implemented a large amount of new multiplayer functionality. The overall system is a work in progress and will be completed in build 128. The primary enhancement in this release is a new message journal that stores certain controller messages. The journal is sent to client machines when they join a game in order to update the state of various controllers before the current world is displayed. When a client machine receives the messages in the journal, it plays them as if it had been connected to the server all along, ensuring that the correct state is set for controllers that have changed since the game was started. * A controller message is added to the Message Manager's journal when it is sent from the server using the <code>MessageMgr::SendMessageJournal</code> function instead of the <code>SendMessageAll</code> function. Journaled messages are also tracked on a per-controller basis, and new messages may override previous messages in the journal for the same controller. The <code>ControllerMessage</code> class now has a virtual function named <code>ControllerMessage::OverridesMessage</code> that is called once for each message in the journal that was previously sent to the same controller. It can inspect the previous message object and return true to knock the previous message out of the journal. * It is now possible to assign a generic controller to a node. The only purpose of the generic controller is to receive built-in controller messages used by the built-in script methods (such as Enable Node and Disable Node). Any node that is the target of a built-in script method must have a controller assigned to it in order to receive the messages send to it by the script. Any type of controller will do, but if the node doesn't have a controller assigned to it for any other purpose, then it will need a generic controller. * Scripts now always run only on the server machine. The "script runs on server only" flag has been removed. * Split the color for light sources into a diffuse color and a specular color. Ordinarily, these are the same, but you can now set a separate specular color for a light source that will be used in the specular component of the shading formula. * Added a brightness scale box to the Get Info dialog for lights. The overall brightness of a light is scaled by whatever number is entered, as long as it's greater than 1.0. * Added a beam effect node that renders a cylindrical beam between two points. The beam is rendered as a quad that always faces the camera. The beam may have a custom texture assigned to it that repeats a given number of times along the beam, or it can use a default built-in texture. * Implemented the Convert to Generic Mesh command in the World Editor. This independently converts each selected geometry into a generic mesh geometry. This will be useful for future vertex/face editing tools because they will only operate on mesh geometries and not primitive geometries. * The Merge Geometry and Convert to Generic Mesh commands now perform internal T-junction elimination. This is very useful if you build up a multi-material mesh by creating several different components that don't necessarily all share the same vertex positions. * The concept of group space has been removed from the engine. Vertex coordinates for a geometry are now always stored in either object space or world space. * Added command line parsing. The same commands that can be put in a <code>CFG</code> file can now be appended to the command line, and these are executed immediately after the <code>Variables.cfg</code> file is executed. Commands are separated by semicolons, and variables begin with a dollar sign. As an example, the following line resets the display resolution to 1024×768 and sets the application module to <code>Skeleton.dll</code>. <code>C4.exe $displayWidth=1024; $displayHeight=768; $applicName="Skeleton"</code> * Further improved the Collada Importer's ability to locate texture files. It will now recognize the substring "/../tga/" and treat anything that comes after it as the full path to a texture image. * The Collada Importer will now recognize multiple objects being instanced for a single node. It's a bit odd for a Collada file to have this (and its legality is questionable), but Google SketchUp likes to do it. * (Bug #0000078) The Collada Importer now imports lights specified in the manner defined by Collada 1.4. * Added two new built-in script methods that enable and disable interactivity for a node. * Added a script function to the panel controller that changes the text for a panel item. * (Bug #0000001) Fixed a problem in the demo game module that would cause a weapon to get stuck in the firing mode if you engaged an interactive object while firing. Interaction events are now simply ignored if you're firing your weapon. * (Bug #0000035) Fixed a problem in the material manager that was not correctly invalidating changed materials on a mesh with multiple materials. * (Bug #0000057) Fixed a problem that prevented subfolders from being created on the Mac when new resources were imported. 642bd6961e217b686b4eaec4194f9fee63154e4c Release Notes for Build 128 0 33 35 2023-07-15T09:38:38Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' October 1, 2006 * The engine now builds as a universal binary on the Mac, but the Intel version has not yet been tested. * Made changes to the Network Manager and Message Manager that are too numerous to list here. The vast majority of the changes are finished, but there will be a few more in the next build, mostly to move some functionality currently in the demo game module into the engine module. * Added a lot of new gameplay code to..." wikitext text/x-wiki __NOTOC__ '''Release date:''' October 1, 2006 * The engine now builds as a universal binary on the Mac, but the Intel version has not yet been tested. * Made changes to the Network Manager and Message Manager that are too numerous to list here. The vast majority of the changes are finished, but there will be a few more in the next build, mostly to move some functionality currently in the demo game module into the engine module. * Added a lot of new gameplay code to the game module: * Players can steer a little bit while falling through the air now (you exert a small propulsive force). * Because you can propel yourself in the air, it is now possible to jump onto something even if you are standing right next to it and can't get any forward motion on the ground. * Motion of client players is now predicted and smoothly corrected in multiplayer games. * Rockets and grenades now do splash damage. * When a player spawns, he has a protection shield for a few seconds. * When you have another player in your sights, his name is displayed. * The weapon balance has been improved—the blaster does a little more damage, and the plasma gun does a little less damage than before. * Added a +100 health power-up (jack-o-lantern model). * Added a Kill Character script method. * The <code>Node::EnumerateNodes</code> function has been updated so that the callback function gets the center and radius of the input sphere. * Added the <code>World::QueryWorld</code> function. This determines whether a fat ray hits environmental geometry, a collider, or nothing. It works like <code>World::DetectCollision</code>, except it returns a collision state constant indicating what was hit. * Added the <code>InvalidateStaticShadowVolumes</code> function to the <code>Geometry</code> class. This wipes out any cached shadow volumes and should be called if an object becomes dynamic after being static. * Added the Import Model menu command to the World Editor. This lets you import an <code>MDL</code> file. * Added amplitude and period settings to the <code>TeleportController</code> class in the Game Module. These control the floating effect for the teleporting remote portals. * Updated the Display Manager code for MacOS X to use newer operating system APIs. This should allow more display modes to be accessible, and there is no longer a dependency on <code>DrawSprocket</code>. * (Bug #0000113) Fixed a crash that would occur if a panel effect was cloned. d2d9c1b5c47aa6646a847ebcf19afb183b578dea Release Notes for Build 129 0 34 36 2023-07-15T09:39:12Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' November 3, 2006 * Designed and implemented an animation blending system. The <code>Entity</code> class can now own a tree of Animator objects that calculate transforms for the node hierarchy rooted at the entity node. Each animator has its own target root node so that it can be assigned to a subtree of the whole entity. Animators can calculate transforms in any way they wish, and the final transforms output by the root animator are ultimat..." wikitext text/x-wiki __NOTOC__ '''Release date:''' November 3, 2006 * Designed and implemented an animation blending system. The <code>Entity</code> class can now own a tree of Animator objects that calculate transforms for the node hierarchy rooted at the entity node. Each animator has its own target root node so that it can be assigned to a subtree of the whole entity. Animators can calculate transforms in any way they wish, and the final transforms output by the root animator are ultimately applied by the <code>Entity</code> class. * '''NOTE:''' Some parts of the animation blending system have been intentionally removed from this release because they are being redesigned. The complete system will be included with the next release. * Implemented horizon maps. It is now possible, while importing a normal map, to generate two auxiliary textures that contain data about how bumps cast shadows onto themselves. When the "Generate horizon maps" check box is selected in the Texture Importer dialog, two additional textures with suffixes <code>-h1</code> and <code>-h2</code> are created along with the normal map. Once these exist, horizon mapping can be enabled for a material by selecting the "Apply horizon maps" check box in the General pane of the Material Manager. Horizon maps can only be applied when a single normal map is present in a material, and they use the same texture coordinates as the normal map. * There is a new setting in the Graphics Options dialog that enables or disables horizon mapping globally. * Removed the two-sided and alpha test flags from the <code>GeometryObject</code> class. These rendering flags can now only be set in a material. * Added a new type of particle that can be used for ribbon/trail effects. When the <code>kParticlePolyboard</code> constant is specified as a particle's style, then the <code>PolyParticle</code> structure must be the base structure used in the particle pool. It contains a tangent direction, a texture coordinate, and a flag indicating whether the particle is the last in a single polyboard. If it is not the last, then the polyboard continues to the next particle in the system. If it is the last, then the next particle begins a new polyboard. The radius of a particle controls the width of the polyboard. * Several big changes have been made to the Message Manager. The <code>PlayerMgr</code> class has been removed from the engine and replaced with a system based on events that are passed to handler functions in the <code>Application</code> class. * Two new general classes have been defined for distributing information to client machines in a multiplayer game. The <code>StateSender</code> class is used to send initial state when a new client joins a game, and the <code>SnapshotSender</code> class is used to send state at fixed intervals during gameplay. * Added a new script function to the <code>PanelController</code> that activates panel items. This runs the scripts attached to the panel items as if the player had clicked on them. * Removed the <code>PositionMarker</code> class and renamed the <code>LocationMarker</code> class to <code>LocatorMarker</code>. All position markers will be converted to locator markers automatically. There was really no need to have two different marker types that essentially mean the same thing. * In the Game Module, the player's weapon is now visible in the first-person view. Both the weapon and the flashlight are now hooked up to a special mount node that the attached to the character. The player's hands do not yet grasp the weapon correctly—we are planning to use IK in a future release to keep the hands in the right place. There are a couple of additional minor issues: projectiles do not yet fire directly out of the weapons, and motion blur around the border of the weapon is not acceptable when the background is in motion. These will both be addressed in a future release. * The geometry building code now splits vertices along edges that are too sharp to share normals. The Collada Importer now preserves the normal vectors on all imported geometry. * The Collada Importer now recognizes the custom bump map settings written by 3DS Max. * The Graphics Manager will now attempt to auto-configure some rendering options. On lower-end graphics chips, some options will be turned off automatically the first time the engine is run. * Fixed a problem in which some geometries in a zone may not be lit properly if the zone is visible through multiple portals simultaneously and a particular light region doesn't intersect all of the camera regions. * Made some small changes to the material manager layout. The two-sided flag, alpha test flag, and texture blend mode menu have been moved to a new Options pane. New settings for enabling horizon mapping in a material are also in the Options pane. * Made several updates to the Texture Importer tool. You can now specify a different output name in the import dialog. The <code>itexture</code> command can now take command line parameters to specify import settings. If any parameters are specified, then the import dialog is not displayed. This allows batch texture imports to be performed by storing a bunch of <code>itexture</code> commands in a <code>cfg</code> file and executing it (with the exec command). See the [[Texture Importer]] page for a description of the command line parameters. * Added a check box to the Texture Viewer tool that lets you turn alpha blending on and off. * Fixed a minor glitch that would cause the in-air propulsion to be too high for the first frame during which the player is falling. This caused a noticeable burst of acceleration on slower machines when you did something like walk off the edge of a platform. d82b28ae0e3c6b05558d5524a2b39bc1ed6b5f49 Release Notes for Build 130 0 35 37 2023-07-15T09:40:24Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' November 10, 2006 * Finished the animation blending system based on a new design. There are three built-in animator subclasses that provide general functionality, and applications can define custom animators for more specific purposes (see next note). Each animator in the tree assigned to an entity targets a range of nodes rooted at a given target node (which is often the entity itself). * The <code>FrameAnimator</code> class is used to pl..." wikitext text/x-wiki __NOTOC__ '''Release date:''' November 10, 2006 * Finished the animation blending system based on a new design. There are three built-in animator subclasses that provide general functionality, and applications can define custom animators for more specific purposes (see next note). Each animator in the tree assigned to an entity targets a range of nodes rooted at a given target node (which is often the entity itself). * The <code>FrameAnimator</code> class is used to play an animation stored in an animation resource. This replaces the functionality that was previously part of the <code>Entity</code> class. The frame animator is based on time instead of frame number, and its rate can be changed arbitrarily. Control over the playback is accessed through the <code>Interpolator</code> object returned by the <code>FrameAnimator::GetFrameInterpolator()</code> function. * The <code>MergeAnimator</code> class can be used to combine the outputs of multiple animators. It takes the outputs of all of its subnodes and combines them into a single output. Later subnodes can override the outputs of earlier nodes. * The <code>BlendAnimator</code> class blends the outputs of at most two sub-animators. The weight of each animator is controlled through another <code>Interpolator</code> object that can be retrieved with the <code>Animator::GetWeightInterpolator()</code> function. Weights are always renormalized by the blend animator, so they don't need to sum to one. * Removed the bone modifier mechanism that was being used to twist the spine of the player as he looked around. This is now handled by a custom animator called <code>SpineTwistAnimator</code> in the game code. * Fixed a bug that could cause a crash on exit when using microfacet shading together with fog. * Fixed a crash that would occur if you combined dual textures, refraction, and environment mapping in a single material. e8b908bf70ffb249e7faea7314c631dd40e903d4 Release Notes for Build 131 0 36 38 2023-07-15T09:40:54Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' November 20, 2006 * Implemented an example of a polyboard particle system. The <code>SpiralHelixEffect</code> class in the Game Module animates a particle system for which every group of 8 particles forms a ribbon. * Added a workaround to the Collada Importer that would handle apparently erroneous bone weights of zero generated by the ColladaMax 1.06 export plugin. * Fixed a scale problem that affected Collada exports from 3D Studio MAX...." wikitext text/x-wiki __NOTOC__ '''Release date:''' November 20, 2006 * Implemented an example of a polyboard particle system. The <code>SpiralHelixEffect</code> class in the Game Module animates a particle system for which every group of 8 particles forms a ribbon. * Added a workaround to the Collada Importer that would handle apparently erroneous bone weights of zero generated by the ColladaMax 1.06 export plugin. * Fixed a scale problem that affected Collada exports from 3D Studio MAX. Models that looked mangled before should now import correctly. * Fixed a problem that could prevent animations from importing correctly. * Fixed a hardware detection problem that could cause shadow mapping not to render correctly on ATI hardware. (A hacky workaround has to be used on ATI hardware because <code>GL_ARB_fragment_program_shadow</code> does not function correctly. 1b184b4009145c2fed48c5f2dc4f195811551de3 Release Notes for Build 132 0 37 39 2023-07-15T09:41:30Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' February 14, 2007 * '''NOTE:''' A lot of changes have been made to the distribution of source code files among the three code directories in this build. The directories have been renamed to "EngineCode", "GameCode", and "ToolCode", without spaces, so unzipping into an existing installation will result in three new code directories being created with clean groups of files. * The World Editor has received a massive upgrade, and the existing..." wikitext text/x-wiki __NOTOC__ '''Release date:''' February 14, 2007 * '''NOTE:''' A lot of changes have been made to the distribution of source code files among the three code directories in this build. The directories have been renamed to "EngineCode", "GameCode", and "ToolCode", without spaces, so unzipping into an existing installation will result in three new code directories being created with clean groups of files. * The World Editor has received a massive upgrade, and the existing editor code has been largely reorganized. It is now structured in such a way that custom editor extensions (plugins) will be possible in a near-term release. * Most of the editor tools have now been organized into palette-like subwindows called "pages". Pages contain groups of related tools and can be arranged on the left side of the editor window by dragging them around. Pages can also be hidden or collapsed, and invisible pages can be shown by selecting them in the new Page menu. The page state is saved and restored for each world separately. * Some previously existing editor features have been moved into new pages. The selection mask buttons are now part of the Selection Mask page, and the show/hide items previously in the View menu are now part of the Visibility page. * The bulk of the manipulator code has been moved out of the engine core and into the World Editor module, and some internal structures have been changed. All saved manipulators will be dumped when worlds are first opened with this build and replaced with new ones. The only impact this has is that certain manipulator state such a node's editor-only visibility state will be reset. * There is a new page called Layout that controls viewport configuration and manipulator appearance. Several new viewport layouts are now possible, and the type of each viewport can be chosen by right-clicking in the viewport itself. All editor viewports will be reset to default configurations when worlds are opened with this build. * A new viewport type has been added to the editor that displays the scene graph hierarchy. Each node is shown with an icon representing its type and either its name or a string describing its type if it doesn't have a name. The collapse boxes in the hierarchy can be used to hide subtrees. Nodes belonging to referenced worlds are shown in a darker color (when referenced world display is on) and cannot be selected. * The node select, rect select, scroll, zoom, and rect zoom tools work in the scene graph viewport in the same way that they do elsewhere. The move tool works as a reparenting tool in the scene graph viewport, allowing you to drag the selection to a new parent node. Nodes cannot be reparented to one of their descendants or to a reference marker, but anything else goes. * The root node can be selected in the scene graph viewport, but it cannot be deleted or reparented. * The concept of a target group has been removed from the editor because its functionality has been superseded by the reparenting capabilities in the scene graph viewport. * The World Settings command has been removed from the editor. It simply opened the Get Info dialog for the root node, and this can now be accomplished by selecting the root node directly and hitting Ctrl-I. * The right-click menu contains two additional items called Frame All and Frame Selection. These center a viewport on either all nodes or just selected nodes and scale so that everything fits into view. * Most node types are now visible and selectable in the perspective viewport. Lights, sources, markers, and effects are represented by cubic icons whose size can be changed in the Layout page. The volumes covered by triggers, spaces, and effects are also visible. * The default grid color in the World Editor is now given by the variable <code>$editorGridColor</code>. * Added a camera placement tool to the World Editor in a new Cameras page. Also, connectors can now be set up so that they can only link to camera nodes. * Added a new interface panel item that displays an image rendered from another camera in the world. This can be used for things like security camera monitors. To use this panel item, a connector must be assigned to the panel effect node and linked to the target camera. Then the same connector key should be assigned to the camera panel item. * A new function that changes the connector key for a camera panel item has been added to the panel controller. This lets a script change which camera is used to render an image for a camera panel item. * Added a new Skybox page that contains a skybox placement tool. A skybox is now added to a world by explicitly placing a skybox node in the root zone. Skyboxes in existing worlds will show up at the world-space origin. Since a skybox is rendered at infinity, the physical location of a skybox node has no effect, but its orientation does affect the angle at which the skybox is rendered. Furthermore, it is now possible to assign a controller to a skybox node so that, for example, it can be rotated or controlled by a script. * It is now possible to assign a material to a skybox node in the World Editor. Such a material affects how a skybox is rendered in addition to the texture maps assigned to the six skybox faces. Only material attributes that pertain to the ambient lighting equation affect the appearance of a skybox. A material can be removed from a skybox using the new Remove Material command under the Node menu. * The Change Material Color script method will now affect any material assigned to a skybox. * Added a new sound source type that plays ambient sounds. These can be placed in a world to serve as containers for music or environmental sounds. Currently, the physical location of an ambient source has no effect. If an ambient source is playing, it can be heard at the same volume everywhere. * The Node Info dialog for an ambient source lets you assign a list of sound files to play. If the source is streaming, then multiple sounds can be attached to the source, and they will play consecutively without interruption. The same file can be listed more than once. * Under the texcoord animation pane in the material manager, the texcoord speed is now displayed numerically, and the allowable range of speeds has been increased. * When geometry is imported into the World Editor, it will now always appear at the same world-space coordinates no matter what zone is currently the target zone. Imported geometry is still added to the current target zone, but it's transform is multiplied by the inverse of the zone's transform to keep it at the location specified in the import file. * The Remove Transform command has been renamed to Reset Transform to Identity, and a new command called Align Position to Grid has been added to the Node menu in the editor. * The Texture Viewer and Texture Importer tools have been merged into a single tool module. * A new check box has been added to the Texture Importer that lets you specify that the RGB channels of the source texture already contain vector information (such as a normal map). Checking this box causes mipmaps to be generated for vectors instead of colors. This option can be accessed on the command line using the <code>-vector</code> switch. * The Model Viewer has been integrated into the World Editor tool module. It's likely that the model viewer will eventually be integrated into the editor window itself so that a separate window isn't even necessary. * The <code>Constructable</code> class template has been changed in a couple of ways that make it more flexible in general and slightly simpler in the default case. All installed custom constructor objects (such as <code>Constructor<Controller></code>) should now encapsulate a function taking a single parameter of type reference to <code>Unpacker</code>. The type to be constructed can be retrieved by calling the <code>GetType()</code> function on the <code>Unpacker</code> object. See the examples in the game modules. * The polyboard rendering code has been improved so that polyboards viewed near-tangentially look better. * Panels now render correctly in fog. Fog must be explicitly enabled for panels by checking a new box in the Get Info dialog for a panel effect node. * New functions have been added to the <code>Controller</code> class called <code>Wake()</code> and <code>Sleep()</code>. When a controller is asleep, it does not receive calls to its <code>Move()</code> function, saving processing time. New script methods for putting controllers to sleep and waking them are now available. * Added a new flag to the script controller that causes a script to loop continuously. If this flag is set, a script will start over when its last method has finished executing. * When a world is loaded, all nodes now have their world transforms updated before they are preprocessed. This means that the world transform of a node is valid inside the <code>Preprocess()</code> function when a world is being loaded. The world transform is not valid inside <code>Preprocess()</code> if this function is called explicitly or indirectly through a call to the <code>AddNewSubnode()</code> function. * The <code>Node::EnumerateGeometries()</code> function has been updated so that the callback function gets the center and radius of the input sphere. * Added a loop callback to the <code>Interpolator</code> class. This allows you to install a function that is called each time an interpolator loops (such as the frame interpolator for the <code>FrameAnimator</code> class). * Modified the RotationController class in the Game Module. The center of rotation and the rotation axis are now specified by adding connectors of type CENT and AXIS to the controller's target node and connecting them to markers. If the AXIS connector is present and connected to a node, then the difference in the positions of the two markers gives the axis of rotation. If there is no AXIS connector, then the rotation axis is the z-axis. These markers should not be subnodes of the node that is actually moved. * Modified the <code>DoorController</code> class in the Game Module. The controller should now be applied directly to the node that gets moved (which can be the root node of a bigger tree). Open, closed, and shifted positions are specified by adding connectors of type OPEN, CLOS, and SHFT to the controller's target node and connecting them to markers. The relative positions of the markers (which can actually be any kind of node) tell the controller how to move the door. These markers should not be subnodes of the node that is actually moved. * Added a new enemy character to the Game Module. The AI for the Pumpkinhead is extremely basic for now, but the code demonstrates how an NPC could be added to a game. The Pumpkinhead can be found in the Dungeon level, and he'll come after you with fireballs. * By fiddling with internal formats, a 75% increase in shadow map rendering speed has been achieved on ATI hardware. * The C4 Engine now runs on PS3. de747d440e6a9b5d3c747f3fb491b203d17c1d51 Release Notes for Build 133 0 38 40 2023-07-15T09:42:21Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' April 6, 2007 * FBOs are now enabled by default on the Mac. They seem to be working correctly in MacOS 10.4.9. * The <code>System</code> class has been removed from the engine, and its functions have been moved to the <code>Engine</code> class. All occurrences of <code>System::</code> and <code>TheSystem-></code> should be changed to <code>Engine::</code> and <code>TheEngine-></code>, respectively. * With the intent of reducing the number..." wikitext text/x-wiki __NOTOC__ '''Release date:''' April 6, 2007 * FBOs are now enabled by default on the Mac. They seem to be working correctly in MacOS 10.4.9. * The <code>System</code> class has been removed from the engine, and its functions have been moved to the <code>Engine</code> class. All occurrences of <code>System::</code> and <code>TheSystem-></code> should be changed to <code>Engine::</code> and <code>TheEngine-></code>, respectively. * With the intent of reducing the number of steps required to register custom class types, the registration mechanism has been changed a bit. First, for all registration types, it is no longer necessary to explicitly call one of the <code>Register*()</code> functions. Instead, every registration type automatically registers itself upon construction. Calls to the following functions should simply be removed: ** <code>RegisterController</code> ** <code>RegisterProperty</code> ** <code>RegisterMethod</code> ** <code>RegisterMutator</code> ** <code>RegisterEffect</code> ** <code>RegisterEntity</code> ** <code>RegisterFunction</code> * Second, there is a new, slightly different way to declare registrations for controllers, properties, methods, mutators, effects, particle systems, and functions. Instead of declaring a controller registration object as a <code>ControllerRegistration</code>, you should declare it as a <code>ControllerReg<type></code> template object, where type is the derived type of the custom controller class. For example, the registraton for the <code>RotationController</code> class is declared as <code>ControllerReg<RotationController></code>. The following templates exist for registering various types of custom classes: ** <code>ControllerReg<type></code> ** <code>PropertyReg<type></code> ** <code>MethodReg<type></code> ** <code>MutatorReg<type></code> ** <code>EffectReg<type></code> ** <code>ParticleSystemReg<type></code> ** <code>FunctionReg<type></code> * Custom class types registered with these templates no longer need to be constructed explicitly by the application. If you've implemented a function such as <code>ConstructController</code>, then you can remove any registered types because they will be constructed automatically. * The function registration object is a little different in that its constructor takes a pointer to a controller registration as its first parameter. Function registrations for each type of controller are stored in the controller's registration object. There is no longer any need to implement a <code>ConstructFunction()</code> function in controller classes that define custom functions. * Previously, registration objects for controllers, properties, and mutators took a parameter that specified some kind of validation function. These have been removed because the new registration templates can call the validation function for the custom class type directly. When a controller or property subclass defines the <code>ValidNode()</code> function (as a static member function), then it is automatically called to determine whether the controller or property can be applied to a particular node. Likewise, defining the <code>ValidPanelItem()</code> function in a mutator subclass will cause that function to automatically be called to determine what kind of panel item the mutator can be assigned to. * Entity and locator registrations still work as they did before since they don't register new subclass types. Continue using the <code>EntityRegistration</code> and <code>LocatorRegistration</code> objects to register these types. * The perspective viewport in the World Editor can now render with full lighting, reflection, refraction, fog, and some effects. There is a new toggle button at the top of the editor window that switches between full lighting and bright ambient rendering. Geometries, lights, etc., can be moved around with full lighting turned on to see the immediate results of your changes. * In the scene graph viewport, hidden nodes are now shown in a darker gray color. Nodes belonging to referenced worlds are shown in a reddish color. * In the World Editor, the Layout page has been renamed to the Viewports page to avoid confusion with a future Layers page. * The mouse wheel will now work at all times in the World Editor to zoom viewports, even when you're doing something else with the mouse button down. * Pages in the World Editor can now be displayed on either the left or right side of the window. This can be changed in the Editor Settings dialog accessible from the Layout menu. * The World Editor now displays a gizmo for selected nodes that shows the orientation of the node's local axes. The gizmo is shown as three arrows with colors red, green, and blue corresponding to the x-, y-, and z-axes, respectively. The gizmo is shown for one node in the selection at a time, and it can be iterated through the selected nodes by pressing the tab key. When the Select and Move tool is used, an arrowhead on the gizmo can be grabbed in any viewport and used to drag the node along its corresponding axis. * In the next build, the gizmo will also have rotation handles, and it will be possible to display world-space and zone-space axes instead of object-space axes. * Added a new Particle Systems page to the World Editor. This page displays a list of registered particle systems (see next item) and also contains tools for drawing emitter volumes. Particle systems now have a built-in connector of type EMIT that can be connected to an emitter volume. How the emitter volume is used depends on the particular particle system's implementation. Multiple particle systems can be connected to the same emitter volume. * Application-defined particle systems can now be registered using the <code>ParticleSystemReg<></code> class. Registered particle systems can be placed in a world using the World Editor. * Particle systems can now be fully serialized, meaning that the state of all active particles is saved. If a custom particle type is defined, then it must implement <code>Pack</code> and <code>Unpack</code> functions that save any custom state in addition to the base state saved with ,code>Particle::Pack</code>. * Added a new particle style called <code>kParticleQuad</code> that causes particles to be drawn as fully oriented quads instead of camera-facing billboards. Particle systems using this style must use the <code>QuadParticle</code> structure to store particles. The <code>transform</code> field of the <code>QuadParticle</code> structure specifies the orientation of each particle as a quaternion. * Added the <code>AddFarthestParticle()</code> function to the <code>ParticleSystem</code> class. This makes the newly added particle the first to render instead of the last, as is the case when the <code>AddParticle()</code> function is called. * Previously, it has been possible to render multiple fog spaces at once as long as they apply to different render targets, but each fog space had to be in a different zone. It is now possible to place multiple fog spaces in a single zone and have them all be considered for rendering (but still only into different render targets). This makes it a lot easier to add fog to areas that already contain a fog space for an underwater volume. * The <code>DoorController</code> now exposes settings for three different sounds: one that plays when the door has fully opened, one that plays when the door has fully closed, and one that loops while the door is moving in either direction. * The demo game module now defines the variable <code>$fov</code> to be the field of view for all cameras, in degrees. The game will clamp the value to the range <code>[45,90]</code>. * The String Importer tool will now translate \t, \n, and \r into tab, newline, and carriage return, respectively. As usual, a backslash can be obtained by using \\. * The <code>TextBoxElement</code> interface class now starts a new line whenever a newline or carriage return character is encountered. The \n is recognized as a newline in the panel editor for text items. * If an attempt is made to load a nonexistent model resource, the engine will now load a stand-in "missing" model instead of throwing an exception. The "missing" model is currently a yellow cylinder. * The shot command will now pad out screenshot index numbers in filenames to four digits. * Added support for 64-bit integers to the <code>String</code> class and <code>Text</code> namespace. * Added a rendering callback to the <code>World</code> class. The <code>World::SetRenderProc()</code> function sets a callback function that is called right after the entire scene has been rendered inside <code>World::Render()</code>, but before the Graphics Manager render target is changed back to the primary surface. This lets you render extra objects directly into the world's render target. * Precached entity models will now be reloaded when a model resource is exported from the World Editor. This removes the need to quit and restart the engine when a model is changed. If the change occurs while clones of the model exist (perhaps because a world is running in the background), then they will not be replaced, but all new instances will use the new model resource. * The Collada Importer tool has been updated to recognize additional material structures that are output by the 3DS Max exporter. a16cdd78f3b230d442ee1106c3ec87eafcc75b4a Release Notes for Build 134 0 39 41 2023-07-15T09:42:58Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' April 14, 2007 * Added a new <code>PolygonZone</code> class that allows a zone to have the shape of an extruded convex polygon. In the World Editor, polygon zones are drawn in a manner similar to portals, in which new vertices can be inserted, and existing vertices can be individually dragged around or removed. The polygonal shape defines the base of the zone, and the height of the zone is controlled by an additional handle at the top cente..." wikitext text/x-wiki __NOTOC__ '''Release date:''' April 14, 2007 * Added a new <code>PolygonZone</code> class that allows a zone to have the shape of an extruded convex polygon. In the World Editor, polygon zones are drawn in a manner similar to portals, in which new vertices can be inserted, and existing vertices can be individually dragged around or removed. The polygonal shape defines the base of the zone, and the height of the zone is controlled by an additional handle at the top center of the zone. * When a node is cloned, links between any pair of its subnodes are now replicated in the cloned subtree. (Any connectors that lead out of the subtree being cloned continue to be cleared in the new copy.) This also affects connectors in referenced worlds, since these worlds are cloned when more than one instance is used in a level. Connectors inside a referenced world will now be replicated in all copies of that world. * In the World Editor, panel effects are now rendered in the perspective viewport when lighting is enabled. Panels are only shown in their initial state because controllers do not run in the editor. * Particle systems are now subclassed from the <code>Configurable</code> class and can expose settings in the World Editor. If a particle system exposes any settings, then a Particles pane will appear in its Get Info dialog. * Several improvements have been made to the burning rain effect in the demo game. The flames can now be rendered as particles, so a single particle system is used to render all of the flames at once. The <code>BurningRain</code> class also exposes some settings in the editor now. * Added a color setting to the waterfall particle effects in the demo game. * Added the Select Connected Node command to the Node menu in the World Editor. This command is available when one or more connectors are selected, and it selects the nodes that they are connected to. * Added virtual functions <code>BeginRendering()</code> and <code>EndRendering()</code> to the World class. These contain the code previously in the <code>World::Render()</code> function that should only be executed once per frame. The render callback function that could be installed in the last build is no longer necessary since it's exact behavior can now be implemented by overriding the <code>World::Render()</code> function and executing extra code after calling the base class's <code>Render()</code> function. Thus, the <code>World::SetRenderProc()</code> function has been removed. * The <code>Compressor</code> and <code>Decompressor</code> classes now support 64-bit integers for network messages. a004cced8e9b70069b73a042bb11e20a42f4598e Release Notes for Build 135 0 40 42 2023-07-15T09:43:53Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' May 12, 2007 * Antialiasing has been re-implemented in the engine using the <code>GL_EXT_framebuffer_multisample</code> extension. The number of samples per pixel can be set in the Graphics Settings dialog, and the engine supports up to 8 samples when available. * The weapon code in the demo game has received a big upgrade. All weapons now shoot precisely from their barrels. More importantly, the proton cannon is now implemented. When it's..." wikitext text/x-wiki __NOTOC__ '''Release date:''' May 12, 2007 * Antialiasing has been re-implemented in the engine using the <code>GL_EXT_framebuffer_multisample</code> extension. The number of samples per pixel can be set in the Graphics Settings dialog, and the engine supports up to 8 samples when available. * The weapon code in the demo game has received a big upgrade. All weapons now shoot precisely from their barrels. More importantly, the proton cannon is now implemented. When it's fired, the barrel takes a moment to spin up before the beams actually shoot, but the gun has a devastating effect on its target. * The configuration interface for customizable settings has been completely reworked. It now displays a two-column scrollable list of settings. Slider-based settings now also accept text entry. The only affect this has on existing code is that the <code>TextSetting</code> constructor no longer takes a width parameter. * There is a new <code>HeadingSetting</code> class that lets you insert a section heading into a list of settings. * There is a new Transform page in the World Editor that displays the position, rotation, and size of the node for which the gizmo is currently shown. (Remember that the gizmo can be advanced through the selected nodes by pressing Tab.) Entering new data in the Transform page has an immediate effect on the node. All changes to the position and rotation are clumped together for a single undo step, and all changes to the size are clumped together for a separate single undo step. Keyboard focus in the Transform page is ended whenever you click in a viewport, select one of the standard tools at the top of the editor, or hit the Escape key. * The size fields in the Transform page require a little explanation. These aren't to be confused with scales, which are not included in transformation matrices in C4. All objects that have well-defined sizes can express their dimensions using 1&ndash;4 measurements. For most primitive geometries, the measurements correspond to the size of the geometry in the ''x'', ''y'', and ''z'' directions. The annulus and hole primitives are exceptions where two numbers correspond to the size of the inner boundary, and two numbers correspond to the size of the outer boundary. For things like lights and sound sources, the first size parameter corresponds to the light's range. * There is a new Info page in the World Editor that displays various kinds of information about the node for which the gizmo is currently shown. Currently, the Info page displays the node name, the controller type, the number of connectors, and the number of properties for every type of node. For geometry nodes, the Info page also displays the vertex count, face count, surface count, material count, and detail level count. More information may be added in a future release. * There is a new Grid page in the World Editor that contains controls for all grid-related settings. The toggle buttons for showing gridlines, snapping to the grid, and showing the coordinate axes have all been moved to the Grid page. The settings for gridline spacing and grid color have also been moved to the Grid page from their previous home in the Editor Settings dialog. There is a new setting called "major grid" that specifies how many grid squares separate each brighter major gridline. There are also two new buttons that immediately double or halve the gridline spacing. * The grid snap mechanism in the World Editor has been changed. Instead of being applied to everything, grid snap is now only applied where it makes sense. In general, grid snap is applied when nodes are placed, moved, or resized. Furthermore, grid snap now applies when nodes are moved in the perspective viewport. * The motion blur algorithm has been upgraded in several ways. It's now more accurate, and it takes depth gradients into account so that distant objects don't blur together with close objects. Previously, you could see a halo around the weapon in the demo game because the background was moving, but the weapon was stationary with respect to the camera. This no longer happens, and additionally, the spinning barrel of the proton cannon won't blur with the stationary parts of the same gun. It was not possible to implement the motion blur as nicely on ATI hardware because the ATI drivers do not support derivative instructions in <code>ARB_fragment_program</code>. So the ability to separate motion blur into different depth layers is limited on ATI hardware, but it's still better in this release than in the previous ones. In particular, the engine can't stop the stationary part of the proton cannon from blurring into the spinning barrel on ATI hardware. Derivative instructions are available on ATI hardware in GLSL, but GLSL has serious limitations that don't exist in <code>ARB_fragment_program</code>, such as a lack of shared global variables, that have prevented the engine from using it. * The cursor in an interface panel no longer blurs into the rest of the panel when the camera moves (since it's stationary with respect to the camera). Again, this isn't 100% perfect on ATI hardware for the reasons mentioned above. * The Script Editor will now automatically assign generic controllers to nodes that are the targets of script methods, but don't already have controllers assigned to them. This removes the extra step that was necessary before in order for a script method to send messages to a node. * Added a new function called <code>SetInputManagementMode</code> to the Interface Manager class. Passing <code>kInputManagementManual</code> to this function will stop the Interface Manager from changing the input mode based on whether a window capable of receiving events is currently active. Passing <code>kInputManagementAutomatic</code> to the function will cause the Interface Manager to switch the input mode to gameplay mode whenever all interactive windows are closed. bb04b638a6f94fe31043a5cc2c3264289984173f Release Notes for Build 136 0 41 43 2023-07-15T09:44:22Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' May 22, 2007 * There have been several problems with input not responding on the Mac lately. This issue has been traced to behavior changes in some MacOS X HID Manager functions introduced by the latest security updates from Apple. Some users would have started experiencing the problem after upgrading to MacOS 10.4.9, and other users would have seen the problem only after installing security update 2007-004. A workaround has been implemente..." wikitext text/x-wiki __NOTOC__ '''Release date:''' May 22, 2007 * There have been several problems with input not responding on the Mac lately. This issue has been traced to behavior changes in some MacOS X HID Manager functions introduced by the latest security updates from Apple. Some users would have started experiencing the problem after upgrading to MacOS 10.4.9, and other users would have seen the problem only after installing security update 2007-004. A workaround has been implemented in the engine, so all input problems on the Mac should now be resolved. * Added some new optimizations to the shadow culling code that will stop unnecessary shadows from being drawn in some cases. * Added a new feature to the motion blur effect that uses fast-clearing hardware to initialize the velocity buffer to the correct background velocity when appropriate. This allows motion blur to be applied when the clear color is being used in a world, and it provides a more optimal way to set the velocity of a skybox. There is no case in which this has any additional performance cost. * Improved the quality of horizon mapping when used in conjunction with parallax mapping. * Fixed several minor bugs in the world editor and demo game. b5551084d099f1a3d8e4ab7a73a48cd2be69db15 Release Notes for Build 137 0 42 44 2023-07-15T09:45:47Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' August 4, 2007 * The Sound Manager has been almost completely rewritten and now includes a much larger set of features. More important than the number of features, though, is the fact that every single feature is available on all platforms and with all sound hardware. The engine no longer contains any support for vendor-specific libraries like EAX and instead uses a custom multi-threaded software audio renderer. This gets rid of all the hea..." wikitext text/x-wiki __NOTOC__ '''Release date:''' August 4, 2007 * The Sound Manager has been almost completely rewritten and now includes a much larger set of features. More important than the number of features, though, is the fact that every single feature is available on all platforms and with all sound hardware. The engine no longer contains any support for vendor-specific libraries like EAX and instead uses a custom multi-threaded software audio renderer. This gets rid of all the headaches associated with supporting different hardware, buggy drivers, and poorly designed APIs. Furthermore, it means that the audio experience is identical on all machines, so testing across a wide spectrum of sound hardware is not necessary. * The following list briefly describes the new features in the Sound Manager: ** All sounds can now have any loop count. Previously, spatialized sounds could only play once or loop forever. ** The previously-existing sound classifications (effects, music, voice) have been removed and replaced by registered sound groups. A game module can define any number of sound groups for which the volume can be independently controlled. ** WAV files no longer need to have a sampling rate of 22.05 kHz or 44.1 kHz. The Sound Manager will play WAV files using any frequency. ** The playback frequency of a sound can be changed while it is playing, and the Sound Manager ensures a smooth transition without popping artifacts. ** A Doppler shift can be applied to a sound based on the relative velocity between it and the listener. ** A very precise sound travel delay can be applied based on the distance between a sound and the listener. When a sound is played, this delay is calculated using the current distance to the listener, but the motion of the listener will also be taken into account so that the sound begins playing at the right time. ** Atmospheric absorption can be applied to a sound based on distance from the listener. This attenuates high frequencies so that distant sounds are muffled somewhat. ** The Sound Manager includes a full reverberation model and supports multiple simultaneously active environments. A new type of space node, an <code>[http://c4engine.com/docs/WorldMgr/AcousticsSpace.html AcousticsSpace]</code> has been added that defines the size and reflective properties of an acoustics environment. The listener does not need to be in the same environment as a sound in order for the correct reverberation effects to be audible. ** The volumes of early reflections can be set on a per-environment and per-sound basis. There is a separate setting for high-frequency attenuation of reflected sound. Each environment also has a reverberation decay time associated with it. ** Directional sounds are now supported. As the listener moves through a sound cone for a directional sound, the volume falls off to the exterior volume at the cone's boundary. The exterior volume and extra high-frequency attenuation are applied outside the sound cone. ** Sounds can be attenuated by obstructions. There are separate obstructive volume settings for the direct path and for reflected paths. The <code>AcousticsProperty</code> has been updated for the new obstruction settings. ** Sounds use a new fall-off model, and there is a new sound permeation system that determines how sounds travel throughout worlds. Sounds will now penetrate much more deeply through different zones, traveling down halls and around corners until they naturally become too faint to be heard. Some aspects of the new Sound Manager are still a slight bit rough and will get some tweaking in the next few builds. Acoustics environments have been added to a few of the worlds that ship with the engine, but not all of them. * Some additional audio features that will be added to future releases include direct mixing to multi-channel surround sound and a generalized streaming mechanism that will allow plugin decompressors. * For various reasons, all C++ exception handling has been removed from the engine. This resulted in significantly smaller binaries, and execution speed should be slightly faster due to the removal of some code and space overhead. If you have a custom project, be sure to turn off support for exception handling in the code generation properties. * As a consequence of there being no exception handling, many error handling mechanisms in the engine had to be reworked. The design pattern for constructors that used to throw exceptions to indicate failure had to be changed to a pattern in which the constructor doesn't really do anything, and a separate initialization function is called. The most prominently affected classes are <code>File</code>, <code>Sound</code>, and <code>Movie</code>. The constructors for these classes no longer take any parameters. The <code>File</code> class now has <code>Open()</code> and <code>Close()</code> functions, and the <code>Sound</code> and <code>Movie</code> classes now both have a <code>Load()</code> function. * In the World Editor, the Get Info dialog now displays settings for all selected nodes simultaneously. Making changes to the settings has an effect on every selected node when the Get Info dialog is closed. Every type of setting can now assume an indeterminate state that is used when values from multiple nodes conflict. If a setting is left in the indeterminate state, then its value is left unchanged for all nodes. The appearance of the indeterminate states are as follows: check boxes show a dash instead of an X, sliders do not show a handle, popup menus show a blank selection, and both color boxes and text boxes are filled with a striped pattern. * Several node settings have been moved or changed to work better with the new Get Info dialog: * The "Do not render through remote portals" setting for geometries has been moved to a subsection under the Node pane because it is a setting for the geometry node and not the geometry object. * The "Do not share light object data" setting for lights has also been moved to a subsection under the Node pane because it represents a general node flag. * The "Light is statically confined" setting for lights has been removed. Controllers that make lights move in a small volume now set the confined flag automatically when the "Light is static" flag has been set in the editor. * The clear color property of the root zone is now exposed as an actual property. This was a property all along, but it was previously shown under the Zone pane instead of the Properties pane. * Several upgrades have been made to the weapons code in the demo game: * Three check boxes have been added to the Player Settings dialog that control automatic weapon switching. The game can be configured to automatically change weapons when you pick up a new weapon or when you run out of ammo. * There are new ammo packs for the grenade launcher, rocket launcher, plasma gun, and proton cannon. * The proton cannon now does a reasonable amount of damage per unit time. * The code for the Display Settings, Audio Settings, and Control Settings dialogs has been moved to the demo game module. * Added a new setting type called <code>PowerTwoSetting</code> that displays a slider and allows the user to choose a power of two between a minimum and maximum value. * Added a new setting type called <code>MultiResourceSetting</code> that displays a text box containing a semicolon-separated list of resources. * The <code>ResourceSetting</code> and <code>MultiResourceSetting</code> settings now display the file picker with texture preview when the resource type is a texture map. * The Interface Manager now maintains a global clipboard for text. Copy, cut, and paste are now supported for all editable text boxes, and this is independent of the World Editor's clipboard for nodes. * The <code>TypeToString</code> and <code>StringToType</code> functions have been moved into the <code>Text</code> namespace. Furthermore, <code>TypeToString</code> now returns a string instead of taking a pointer to an array of characters as a parameter. * Added a <code>[http://c4engine.com/docs/System/Thread_SetThreadPriority.html SetThreadPriority()]</code> function to the <code>Thread</code> class. * Changed the <code>[http://c4engine.com/docs/System/Signal_Wait.html Signal::Wait()]</code> function so that it takes a timeout parameter. * The engine now ships with a new project called SimpleChar. This project contains a simple example of an implementation of a subclass of the <code>CharacterController</code> class and let's you run a character around the world. This game module can be run by changing the <code>$applicName</code> variable (in Data/cfg/Variables.cfg) to "SimpleChar". As with the SimpleBall game module, you need to open the console and use the <code>load</code> command to load a world. a8e7e1c23cad6299abc694e7281506374b26fa03 Release Notes for Build 138 0 43 45 2023-07-15T09:46:25Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' August 18, 2007 * A new script method called "Change Settings" has been added to the core scripting system. This method lets a script change the same settings for an object that are displayed in the World Editor's Get Info dialog. Not all of every object's settings are exposed to scripts because there are some things that can't be changed dynamically, but in general, any object setting for which it makes sense to change can now be changed b..." wikitext text/x-wiki __NOTOC__ '''Release date:''' August 18, 2007 * A new script method called "Change Settings" has been added to the core scripting system. This method lets a script change the same settings for an object that are displayed in the World Editor's Get Info dialog. Not all of every object's settings are exposed to scripts because there are some things that can't be changed dynamically, but in general, any object setting for which it makes sense to change can now be changed by a script. A single method can change any number of settings from a single settings category (each tab in the Get Info dialog represents a separate category), and each changed setting generates a journaled message that overrides any previous changes to the same setting. In the Script Editor, once a target has been chosen for the Change Settings method, a list of available categories appears. Clicking on a category causes the settings in that category to be displayed. Initially, all of the settings are in an indeterminate state, meaning that they are not changed by the script method. Modifying a setting causes it to be added to the method. The settings can be put back into the indeterminate state by clicking the Reset button. * The Change Light Color script method has been removed because it has been subsumed by the Change Settings method. * The <code>Function::Execute()</code> function now takes a <code>[http://c4engine.com/docs/Controller/ScriptState.html ScriptState]</code> object as a second parameter so that it's possible to retrieve information about the activator and trigger nodes. * The Script Editor and Panel Editor will now accept the Enter and Escape keys as shortcuts for the OK and Cancel buttons. If the Cancel button is clicked, or the Escape key is pressed, and changes have been made, a confirmation dialog is displayed. * The Script Editor and Panel Editor windows are now resizeable. * Added the Ticker mutator to the panel effect code. This mutator can be applied to a text item to make the text scroll left or right and be clipped against the edges of the item's bounding box. A new check box in the Panel Editor lets you choose to put the text all on one line, and this must be checked for the Ticker mutator to do anything. * The Texture Importer tool now supports 8-bit grayscale TGA files. * Added a rotation menu to the animation import picker in the Model Viewer. This lets you rotate a character by any multiple of 90 degrees and hardwire it into the animation. * Made several additions to the Collada Importer tool to handle various quirks in the exporters out there. * Implemented several bug fixes and minor feature requests that aren't listed here. 172e4140a9014e3a3731d94fe2b6c961ebce5d75 Release Notes for Build 139 0 44 46 2023-07-15T09:46:51Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' August 21, 2007 * Implemented a workaround for an ATI driver crash that some people have been experiencing. * Fixed a couple minor bugs in the engine." wikitext text/x-wiki __NOTOC__ '''Release date:''' August 21, 2007 * Implemented a workaround for an ATI driver crash that some people have been experiencing. * Fixed a couple minor bugs in the engine. f6139d313bb6b36f313f2def6e7e0d1254523dc9 Release Notes for Build 140 0 45 47 2023-07-15T09:47:43Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' September 27, 2007 * '''IMPORTANT:''' It is particularly important that you backup your resources before installing this build. The World Editor will throw away obsolete information when you open files, and worlds will be saved in an updated format. * After installing build 140, you should open each of your worlds in the World Editor and then immediately save them to automatically update them to the new format. Resource sizes will decrease..." wikitext text/x-wiki __NOTOC__ '''Release date:''' September 27, 2007 * '''IMPORTANT:''' It is particularly important that you backup your resources before installing this build. The World Editor will throw away obsolete information when you open files, and worlds will be saved in an updated format. * After installing build 140, you should open each of your worlds in the World Editor and then immediately save them to automatically update them to the new format. Resource sizes will decrease a bit depending on how many generic meshes each world contains. Models should also be opened in the Model Viewer and then immediately saved to update those as well. * If you have any worlds or models that have not been opened and saved for a very long time, then you should open them and save them in build 139 before installing build 140. Specifically, any resources not saved in build 112 or later need to be opened and saved in build 112&ndash;139 before installing build 140. Some very old backwards compatibility mechanisms have been removed from build 140, and this could cause information to be lost if resources aren't first updated in a previous build. * All geometry building code in the engine has been completed rewritten. The World Editor no longer relies on the existence of a separate source of polygon data for generic meshes, and a lot of support for obsolete mesh operations has been removed. Even though most of this rewrite pertains to internal functionality that is transparent to the user, the completion of this task opens the door for much faster implementation of new geometrical editor features. * Most of the new geometry building code is concentrated in the <code>[http://c4engine.com/docs/WorldMgr/GeometryLevel.html GeometryLevel]</code> class, which represents a single level-of-detail for a geometry object. Non-primitive (generic) geometries are no longer implicitly rebuilt when certain operations are performed on them in the editor. Primitive geometries are rebuilt when they are changed, and they can be explicitly rebuilt by the user. Imported geometries are always generic, and normals for imported geometries are always preserved. Normals can be explicitly recalculated in the editor, however (see next item). * The Node menu in the World Editor has been split into a Node menu and a Geometry menu. The Geometry menu contains two new commands, Rebuild Primitive and Recalculate Normals. * The Rebuild Primitive command has limited utility in this build, but it will become a lot more useful in future builds when edits have been made to a primitive geometry and you want to restore it to its original state. One present use for this command is to restore natural texture coordinates after they've been altered. * The Recalculate Normals command recalculates all of the normals for selected geometries. This is useful for replacing bad normals on imported geometries. When normals are recalculated, so are the tangents. * A primitive geometry will no longer remember that it has been inverted by the Invert Geometry command. If a primitive is rebuilt, then the inversion will be lost. There is a new flag in the Get Info dialog for primitive geometries that causes them to be built inverted, and this should be used to permanently invert a primitive. * The CSG operations (intersection, union, subtraction) in the World Editor have received a major upgrade. They are now capable of handling much more complex geometry, and they generate very clean meshes using some new geometry optimization operations. There are still some precision-related issues with high-density meshes and complex topologies, but the CSG operations can do a lot more than they could before. * The resize tool has been completely rewritten for generic meshes. * A new Mesh Tools page has been added to the World Editor. It currently contains only one tool, and that tool selects individual surfaces on a geometry. (A surface is a group of faces which, as a whole, has a tangent space domain and material that is independent from other surfaces belonging to the geometry.) Clicking on a geometry with the surface selection tool will select the surface containing the triangle that you clicked on. The Shift key can be used to select multiple surfaces, and it's possible to select surfaces from multiple geometries simultaneously. The highlight color for selected surfaces is given by the <code>$surfaceColor</code> system variable. * If individual surfaces are selected on a geometry, then the Set Material command in the Geometry menu now replaces materials only on those surfaces, leaving the materials on other surfaces unchanged. If a geometry is selected, but none of its individual surfaces are selected, then the Set Material command replaces the material for all of the geometry's surfaces. * The Select by Material command in the Edit menu now selects all of the individual surfaces using the current material instead of entire geometries. * A new Texture Mapping page has been added to the World Editor. It contains tools for offsetting, rotating, and scaling texture coordinates. It also contains type-in boxes for the texcoord generation transform and popup menus for the coordinates generation modes. This replaces the Texturing tab which used to exist in the Get Info dialog for a geometry node. (The Texturing tab has been removed.) * When an entire geometry is selected, the texture offset, rotate, and scale tools apply to all surfaces of the geometry. If individual surfaces of a geometry are selected, then texture operations only affect the selected surfaces. * The texcoord generation transform information appears when exactly one surface is selected. Two offsets (one for each of the s and t coordinates), two scales, and a single rotation value can be changed by entering new numbers in the text boxes, and the changes take affect immediately. For undo, the Texture Mapping page works like the Transform page: any contiguous sequence of inputs for offset, scale, rotation, or mode is treated as a single undoable action. Also like the Transform page, keyboard focus is ended whenever you click in a viewport, select a standard tool at the top of the editor window, or hit the Escape key. * Operations that combine multiple geometries into one now generate as many detail levels as the maximum number existing in any of the input geometries. The applies to the Merge Geometry, Intersect Geometry, and Union Geometry commands in the World Editor. * The <code>FunnelGeometry</code> primitive geometry type has been removed from the engine. The same type of shape will be achievable in the World Editor using a revolved path in an upcoming release. Any existing funnel geometries will disappear when a world containing them is opened in this build. To keep the funnels, convert each one to a generic mesh using a previous build. (Select all of them and hit Ctrl-Shift-C in the World Editor.) * Eight flags have been added to the cloth geometry to control which vertices are fixed in position. This is a temporary solution that allows control over whether each of the four corners or four edges of a cloth geometry is fixed. The flags appear in the Get Info dialog under the Geometry tab. * The utility window that has been called "Graphics" is now called "Stats", and the <code>graf</code> command has been changed to <code>stat</code>. This window now displays four new stats, two for textures and two for sound sources. For textures, the window shows the current number of textures loaded and the total amount of memory used by the textures. For sound sources, the window shows the current number of playing sources and the number of those sources that are currently engaged. (A source is considered playing if it would be audible when you're close enough to it, and it's engaged when you actually are close enough to it for the engine to need to send it through the Sound Manager. * Additional mouse wheel support has been added in various places. In particular, the mouse wheel will now scroll the pages in the World Editor and the materials in the Material Manager. * Added the <code>Stop()</code> function to the <code>[http://c4engine.com/docs/Controller/Method.html Method]</code> class. This function should be called from within the method's <code>Execute()</code> function to indicate that the method's subnodes should not be executed, effectively stopping execution of the script along the branch containing the method for which <code>Stop()</code> is called. * Added the static <code>Sleep()</code> and <code>Yield()</code> functions to the <code>[http://c4engine.com/docs/System/Thread.html Thread]</code> class. These functions can be used to temporarily suspend execution of the current thread. * Added the <code>Complete()</code> function to the <code>Thread</code> class. This function can be used to poll for the completion of thread execution. * The Textue Importer dialog contains a new check box that causes the green channel of the output texture to be inverted. This is useful for changing handedness on precomputed normal maps. The command line switch is <code>-invgreen</code>. * In the World Editor, holding in the Ctrl key (or Cmd key on the Mac) while clicking in the Selection Mask page will now cause the mask buttons for all other node types to be unselected. * The Memory Manager has been upgraded. It is now safe to allocate or deallocate memory from any thread. * The C4SIMD define has been removed from the engine. SSE code will now always be compiled, but the engine will only call SSE functions if the processor supports SSE2 instructions. 77eda2b745adb916b68809d1657f70e631c22738 Release Notes for Build 141 0 46 48 2023-07-15T09:48:17Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' October 3, 2007 * The Info page in the World Editor now displays the number of instances in the scene corresponding to the node for which the gizmo is currently shown. The number of instances is equal to the total number of nodes referencing the same data object. * When replacing materials on individual surfaces of a geometry that has multiple instances in the scene, the World Editor now enforces the preservation of the material segmentati..." wikitext text/x-wiki __NOTOC__ '''Release date:''' October 3, 2007 * The Info page in the World Editor now displays the number of instances in the scene corresponding to the node for which the gizmo is currently shown. The number of instances is equal to the total number of nodes referencing the same data object. * When replacing materials on individual surfaces of a geometry that has multiple instances in the scene, the World Editor now enforces the preservation of the material segmentation structure in order to prevent mismatches among the different instances. What this means is that you can't change the number of material slots or the surface-to-material-slot mapping for geometries having multiple instances in the scene. The only consequence of this rule is that attempting to change the material for a set of surfaces on an multiply-instanced geometry may result in the material being applied to more surfaces than are selected. * Added the Copy Transform and Paste Transform commands to the Edit menu in the World Editor. These commands copy and paste the local node transform corresponding to the node for which the gizmo is currently shown. They do not copy and paste the node size (since that's not part of the transform), but just the position and rotation. The transform clipboard is independent from the main clipboard. * Added the Combine Detail Levels and Separate Detail Levels commands to the Geometry menu in the World Editor. These commands allow you to combine multiple geometries into a single geometry with multiple levels of detail, or to separate multiple levels of detail in a single geometry into multiple geometries with a single level of detail. * The Combine Detail Levels command is available when 2–4 geometries are selected. It examines the highest level of detail from each geometry and puts them in order by vertex count. The geometry having the most vertices is designated the primary geometry node, and it continues to exist after the detail levels are combined. The highest level of detail from each geometry is added to the primary geometry as a lower detail level, replacing any lower detail levels that were already there. The geometry data from each input geometry is transformed into the coordinate space for the primary geometry. (Geometries should be manually aligned before combining detail levels.) Input geometries other than the primary geometry are finally deleted. * The Separate Detail Levels command has the opposite function. It takes an input geometry and creates new geometry nodes for each level of detail, removing them from the input geometry. The new geometry nodes are identical to the input geometry, including controller assignment, properties, and connections. However, the collision data will be rebuilt for level 0 if it had been changed. * The collision detail level is now exposed in the Get Info dialog under the Collision tab. By default, collision detection information is generated for the highest level of detail (level 0) for a geometry. This can now be changed so that collisions occur against a lower level of detail. The advantages to setting a higher-numbered collision detail level (which corresponds to lower geometric level of detail) are that it saves space and it performs a little faster. If the collision detail level is set greater than or equal to the number of geometric detail levels, then the last available level of detail is used. * A check box called "Reflection" has been added to the Texture Mapping page in the World Editor. Checking this box will cause texture coordinates to be mirrored in the s direction, effectively adding an inversion on top of the reflection in the texture coordinate generation matrix. Mirroring in the t direction can be achieved by rotating 180 degrees after checking the Reflection box. * An alignment plane popup menu has also been added to the Texture Mapping page. This allows selection of the XY, XZ, or YZ plane as the texcoord generation plane. These are set automatically by many primitive geometries, but may need to be changed for imported geometry to get the desired mapping. * The default texture used when a texture resource is missing has been changed so that it works better as a normal map. (The file is <code>Data/tex/C4/missing.tex</code>.) This texture now looks like a bunch of green Xs on top of a pastel purple background (representing the (0,0,1) normal vector). * The <code>Constructable::Construct()</code> function has been changed to take a second parameter. Any custom construction functions (for custom objects, properties, controllers, etc.) will need to be altered so that they take a second parameter of type unsigned long for additional flags to be passed in. The value of the flags parameter can safely be ignored. * Fixed a crash that would occur only on PowerPC-based Macs when streaming sounds were played. 58aa3671a98012e8e78988c39804aee3f2f7e7a3 Release Notes for Build 142 0 47 49 2023-07-15T09:49:12Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' October 9, 2007 * The Tool Manager has been renamed to the Plugin Manager. The <code>Tool</code> class is now the <code>Plugin</code> class, the <code>ToolMgr</code> class is now the <code>PluginMgr</code> class, and the <code>Tools</code> folder is now the <code>Plugins</code> folder. * A new feature has been added to the in-game interface panels that allows an impostor image to be displayed beyond a given distance instead of the set of e..." wikitext text/x-wiki __NOTOC__ '''Release date:''' October 9, 2007 * The Tool Manager has been renamed to the Plugin Manager. The <code>Tool</code> class is now the <code>Plugin</code> class, the <code>ToolMgr</code> class is now the <code>PluginMgr</code> class, and the <code>Tools</code> folder is now the <code>Plugins</code> folder. * A new feature has been added to the in-game interface panels that allows an impostor image to be displayed beyond a given distance instead of the set of elements in the panel. This can improve performance considerably when many panels are visible at once. The impostor image will cross-fade with the real panel between two distances that can be set in the Get Info dialog under the Panel tab. An impostor image should be a 2D texture so that mipmapping is supported. It is possible to change the impostor image from a script using the Change Settings method. * A geometry detail level bias and shader detail level bias have been added to the Get Info dialog for geometry nodes. These are specified in units of fractional detail levels. A value of 1.0 means to use a detail level that's exactly one level lower quality than would normally be selected. Negative values can be used to keep higher detail at farther distances. * A detail level bias setting has been added to remote portals and panel cameras. This value is added to the detail level that would normally be selected by the engine (in addition to per-geometry detail level biases) and can be used to boost performance when rendering reflections, refractions, or panel cameras. * A simple <code>[http://c4engine.com/docs/EffectMgr/QuadEffect.html QuadEffect]</code> class has been added to the engine for cases when you just need to render a single billboarded quad. It has a position, radius, color, and texture. It gets rendered in the sorted transparent effect pass. * Calling the <code>Entity::SetRootAnimator()</code> function now causes the new root animator to be invalidated, so it's no longer necessary to invalidate it through a separate call to <code>Animator::Invalidate()</code>. * Added settings to the <code>DoorController</code> in the demo game that control the opening speed and closing speed of a door, the time that a door stays open, and whether the door is initially open or closed. * Added a generic rain particle system to the demo game. Also added a new setting to the burning rain particle system that controls what percentage of the rain drops turn into flames. (Note that setting the rain intensity and burning rain percentage too high in combination can result in the flame particle system periodically running out of free particles.) * Implemented a fallback mechanism for missing fonts. If an attempt to load a nonexistent is made, then the default GUI font is loaded in its place. * The middle mouse button now pans viewports in the World Editor. * The Collada Importer now recognizes any empty node whose name begins with MARKER_ as a locator marker. This will prevent an empty leaf node from being deleted during import. When the marker is imported, the first 7 characters are stripped from the beginning of the node's name. * The Graphics Manager now allows three texture quality settings, and this is exposed in the Graphics Settings dialog in the game code. The high quality setting causes the highest-resolution mipmap to be used, and the medium and low quality settings remove the top one or two mipmaps, respectively. Any mipmaps having a resolution higher than that supported by the hardware are also removed. * Added an icon to the multiplayer game that appears over a player's head when he's typing a chat message. * Made some adjustments to the weapon code in the demo game so that shots are no longer fired parallel to the line of sight, but instead in a slightly bent direction based on how far away the target in the crosshairs is. This precisely aligns the projectile's destination with the center of the crosshairs. 44282cd255d46e6d54d89892f62a0ac3196bf6af Release Notes for Build 143 0 48 50 2023-07-15T09:49:50Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' October 19, 2007 * Reference markers can now be expanded and collapsed dynamically from code using the <code>ReferenceMarker::Expand()</code> and <code>ReferenceMarker::Collapse()</code> functions. * The <code>TextElement</code> interface element class has been rewritten and now combines all of the functionality that was previously spread over four different classes. Several new features have also been added that can be used almost everywh..." wikitext text/x-wiki __NOTOC__ '''Release date:''' October 19, 2007 * Reference markers can now be expanded and collapsed dynamically from code using the <code>ReferenceMarker::Expand()</code> and <code>ReferenceMarker::Collapse()</code> functions. * The <code>TextElement</code> interface element class has been rewritten and now combines all of the functionality that was previously spread over four different classes. Several new features have also been added that can be used almost everywhere that text is rendered in the engine, including panel effects. For more information, see the documentation for the <code>TextElement</code> class. * The <code>EditableTextElement</code> class has been expanded to allow multi-line text boxes. This is enabled by setting the <code>kEditableTextMultiline</code> flag with the <code>EditableTextElement::SetEditableTextFlags()</code> function. Multi-line text boxes support all the bells and whistles, including full selection capabilities, copy and paste, mouse wheeling, word wrap, double-click word selection, and smart cursoring. * Made some general improvements to the Panel Editor. One of these is that the text entry box for text items is now a multi-line box. * The Set Panel Item Text script function has been expanded so that you can choose to append or prepend text in addition to replacing it altogether. Also added a way to limit the length of the resulting text. An example that uses this new functionality has been added to the <code>Samples/Lasers</code> world. * Added a truncated cone primitive geometry type. This produces a cleaner mesh than intersecting a cone with a box in many cases. * Some improvements have been made to the CSG code in the World Editor. They can now handle some more topologically complex cases. * Exposed the <code>GetMillisecondCount()</code> function in the Time Manager. This will return a real-time absolute millisecond count, but with no zero reference. ''This function should only be used if you know what you're doing.'' If you have to ask whether it's the right function, then you shouldn't use it. f88b74cde0c92515c17c649bf893531491bad510 Release Notes for Build 144 0 49 51 2023-07-15T09:50:27Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' November 9, 2007 * The Resource Manager has been redesigned and now supports pack files and a virtual directory hierarchy. All resources are still stored inside the Data folder, but the subfolders that previously separated resources by type no longer exist. Resources can now be organized in an arbitrary manner inside the Data folder. However, the top-level contents of the Data folder have special meanings. * All of the top-level subfolders..." wikitext text/x-wiki __NOTOC__ '''Release date:''' November 9, 2007 * The Resource Manager has been redesigned and now supports pack files and a virtual directory hierarchy. All resources are still stored inside the Data folder, but the subfolders that previously separated resources by type no longer exist. Resources can now be organized in an arbitrary manner inside the Data folder. However, the top-level contents of the Data folder have special meanings. * All of the top-level subfolders of the Data folder behave as if their contents belonged to a single virtual folder at the root of the resource namespace. These top-level subfolders exist only for external organization and do not participate in the unique identification of any resources. As an example, suppose that there existed two subfolders <code>Data/Interiors/</code> and <code>Data/Exteriors/</code>. A resource named <code>Wood.tex</code> could be stored in either subfolder, but it would still be identified only as "Wood" by the Resource Manager. The name of the top-level subfolder is not part of the resource's path. However, if the <code>Wood.tex</code> resource was placed in an additional subfolder such as <code>Data/Exteriors/Forest/</code>, then the name of the resource would be <code>"Forest/Wood"</code>. All folder names beneath the top-level subfolders of the Data directory are part of the resource name. * The resources that ship with C4 have been divided into the following subfolders: ** A C4 folder containing the resources used by the core engine and required by all applications built with C4. ** A Demo folder containing the resources used exclusively by the demo game. ** A Tools folder containing the resources used exclusively by the tool plugins. ** A Tutorial folder containing the resources associated with the tutorials and sample worlds. * Pack files, having the extension <code>.pak</code>, can also be stored at the top level of the Data directory. A pack file is created by using a new tool plugin, the Resource Packer, to pack the contents of a top-level subfolder into a single file. The console command <code>pack</code> &lt;''name''&gt; is used to create a pack file, where &lt;''name''&gt; is the name of a top-level subfolder. For example, the command pack Demo will create the file <code>Demo.pak</code> containing all of the resources used exclusively by the demo game. Once a pack file has been created, the folder from which it was made can be deleted, and the Resource Manager will fetch resources from the pack file instead. (Pack files actually override ordinary folders.) * Some additional miscellaneous notes about the Resource Manager: ** Folders and pack files are the only items allowed at the top level of the Data directory. Other types of files in that location will be ignored. ** Resource path names inside pack files are case sensitive. ** QuickTime movies cannot be accessed inside pack files. ** Because concealment is a benefit provided by pack files, there will not be an unpacking tool that would allow users to easily extract resources from a <code>Demo.pak</code> file. * It is no longer necessary to use the <code>ModuleResource</code> class template when defining a resource type in a game module or plugin module. New resource types should now just inherit from the Resource class template. However, the resource descriptor is now declared in the subclass. * The <code>Packable::GetPackSize()</code> and <code>Packable::GetPackTypeCount()</code> functions have been removed from the engine. All overrides of these functions in custom class types should be deleted. These sizes are now calculated automatically by calling the <code>Packable::Pack()</code> and <code>Packable::PackType()</code> functions with a nonwritable data object. * Added a new flag to the script controller that lets you limit concurrent runs of a script to unique activators. That is, with this flag set, only one instance of the script will run for each node that is activating the trigger for the script. * The C4 Sound Manager has been upgraded on the Mac to use the CoreAudio framework. This should provide greater compatibility with future hardware and OS releases as well as yield better performance. * Added a new <code>HashTable</code> class to the engine utilities. * The <code>PrimitiveGeometry</code> class now inherits from <code>Constructable</code> so that custom primitives can be defined by an application. * A new setting has been added to the Texture Import dialog that allows you to select the channel from which height data is read when calculating normal maps, horizon maps, and ambient occlusion maps. The command line equivalent is <code>-height</code> &lt;''n''&gt;, where ''n'' is an integer between 0 and 3 representing the red, green, blue, or alpha channel, in that order. * Since world resources don't all have to be in the same location any more, the demo game now reads the strings in the <code>Data/Demo/game/Worlds.str</code> file to obtain the list of playable worlds displayed in the New Game and Host Game dialogs. The corresponding <code>.txt</code> file in the Import directory can be edited and re-imported (with the <code>istring</code> command) to add or remove worlds from the list. * A new command, Save and Play World, has been added to the World menu in the World Editor. This saves the world being edited, closes the World Editor, and loads the world in the game. f9629b1f0eb488040fe933623038f8a50d4b03c2 Release Notes for Build 145 0 50 52 2023-07-15T09:51:14Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' November 27, 2007 * Implemented a new GUI rendering system. For details, see the wiki article about Creating a GUI Skin. * Added a radio button interface element as the <code>RadioButtonElement</code> class. * Cameras now have a new flag to indicate that they may temporarily move outside their owning zone. This is useful in such cases as a camera mounted on a gun that's attached to a character. A similar flag has existed for lights, and n..." wikitext text/x-wiki __NOTOC__ '''Release date:''' November 27, 2007 * Implemented a new GUI rendering system. For details, see the wiki article about Creating a GUI Skin. * Added a radio button interface element as the <code>RadioButtonElement</code> class. * Cameras now have a new flag to indicate that they may temporarily move outside their owning zone. This is useful in such cases as a camera mounted on a gun that's attached to a character. A similar flag has existed for lights, and now both flags are exposed in the Get Info dialog. * A new concept of "perspective" has been worked into the engine, and this refers to the kind of viewing position the scene is currently being rendered from. There are currently four perspectives defined: direct, reflection, refraction, and camera. The direct perspective pertains to the scene as it is rendered directly from the main camera, the reflection and refraction perspectives pertain to the scene as it is rendered through remote portals, and the camera perspective pertains to the scene as it is rendered through a camera item in an interface panel. Multiple perspectives can be in effect at the same time; for example, the reflection in a water surface seen through a panel camera. * Geometries and fog spaces can now be excluded from each of the four perspectives by setting flags in the Get Info box. (The flags for a geometry appear under the Node tab.) For geometries, the visibility of shadows can also be controlled independently. * A new flag has been added for remote portals that enables recursive rendering. By default, this flag is off, so a remote portal will not be rendered again if you are already looking through that portal. * When shadow maps, cube light projections, spot light projections, or ambient space maps are generated, they are now written into the same virtual directory that contains the world resource from which they were generated. Any subdirectory names in the resource path are relative to the top-level virtual directory. * Added the <code>GetImportResourceCatalog()</code> function to the <code>[http://c4engine.com/docs/WorldEditor/SceneImportPlugin.html SceneImportPlugin]</code> class and the <code>GetExportResourceCatalog()</code> function to the <code>[http://c4engine.com/docs/WorldEditor/SceneExportPlugin.html SceneExportPlugin]</code> class to let the plugins specify what catalog to use for import or export. * Added some resource caching optimizations. * A lot of work has been done to move the PS3 rendering code to a much lower-level system. The Graphics Manager now minimizes use of the GCM library and instead uses custom code to build command buffers. This allows the C4 rendering code to be as fast as possible, and it gives C4 access to more hardware features than are available to other PS3 games. f30854a50aef63c6bd6dd9f70b535e6002113ea6 Release Notes for Build 146 0 51 53 2023-07-15T09:52:26Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' February 7, 2008 * With this release, we begin officially supporting the Intel GMA X3000 series of graphics chips under Windows. Some driver issues are currently preventing us from supporting these chips on the Mac. * A new post-processing effect has been implemented that enables distortion effects such as heat haze. Any effect can be configured so that it renders into the distortion buffer instead of into the main scene by using the <code..." wikitext text/x-wiki __NOTOC__ '''Release date:''' February 7, 2008 * With this release, we begin officially supporting the Intel GMA X3000 series of graphics chips under Windows. Some driver issues are currently preventing us from supporting these chips on the Mac. * A new post-processing effect has been implemented that enables distortion effects such as heat haze. Any effect can be configured so that it renders into the distortion buffer instead of into the main scene by using the <code>[http://c4engine.com/docs/EffectMgr/Effect_SetEffectListIndex.html Effect::SetEffectListIndex()]</code> function to set the effect list to <code>kEffectListDistortion</code> and by setting the <code>kShaderDistortion</code> shader flag. The <code>[http://c4engine.com/docs/EffectMgr/Effect_SetDistortionState.html Effect::SetDistortionState()]</code> function has been provided to set all of the necessary state for rendering into the distortion buffer. * When an effect is rendered into the distortion buffer, only the red and green channels of the texture color matter, and they encode horizontal and vertical offsets, respectively. A value of 128 in either channel means no offset, while 0 means the largest possible negative offset, and 255 means the largest possible positive offset. Offsets are accumulated in the distortion buffer so that multiple effect nodes can have an additive effect on the amount of distortion visible at a particular point. The alpha channel of the vertex color can be used to modulate the intensity of the offset values after RG decoding. See the <code>ShimmerSystem</code> class in the demo game for an example of a particle system that renders heat waves into the distortion buffer. * It is now possible to render effect nodes in the lighting passes so that all of the shading capabilities of the engine can be applied to the effect. This is accomplished by using the <code>Effect::SetEffectListIndex()</code> function to set the effect list to <code>kEffectListLight</code>. An effect must have normal and tangent arrays in order to render correctly in the lighting passes. The marking effect has been extended to create these arrays automatically and set the effect list index. To use this functionality, the <code>kMarkingLight</code> flag should be specified when creating a new <code>[http://c4engine.com/docs/EffectMgr/MarkingData.html MarkingData]</code> structure. The demo game now uses this flag for blood splatters. * The engine now supports a hierarchical relationship among plugins, and it is now possible for a plugin to depend on the existence of other plugins. The way this works is through the use of subdirectories inside the Plugins directory. All plugins in a particular directory are loaded before any plugins in the subdirectories of that directory, so if plugin B depends on plugin A, then plugin B should be in a subdirectory inside the directory containing plugin A. * It is no longer necessary to define <code>C4MODULE</code> when compiling the application module or any plugin modules. Instead, the engine project defines <code>C4ENGINEMODULE</code> so that it can be determined that the engine is being compiled as opposed to any other module. * All of the movie code has been moved into a new Movies plugin. All dependencies on QuickTime are now isolated to this plugin, and the plugin can simply be omitted if movie playing capabilities are not needed. The MoviePlayer plugin depends on the Movies plugin. * A new plugin called Extras has been created that contains functionality that may not be needed by every game, but is general enough to be made available outside the application module. Currently, the Extras plugin includes the rotation controller and the star field particle system. More functionality will be moved to the Extras plugin in the future. * New path editing tools have been added to the World Editor. A path is made up of a series of components that can be any of the types linear, elliptical, or Bezier. A linear component is simply a straight line that connects two endpoints, an elliptical component is a 90-degree elliptical arc between two endpoints, and a Bezier component is a single cubic Bezier curve with four control points (two endpoints and two off-curve control points). Paths are created by using the three tools in the Paths page corresponding to linear, elliptical, and Bezier components. Switching among the tools allows the user to add different types of components to the same path. Whenever a single path node is selected, using the path tools will add to that path. * The path tools will snap to the beginning endpoint of the current path so that perfectly closed paths can be created. The snap can be disabled by holding in the Control key (Command key on Mac). * Control points along a curve can be selected with the ordinary selection tools. Shift-clicking adds or subtracts from a selection. A Control-click (Command-click on the Mac) will cause control points along the tangent to be selected in addition to an on-curve control point in a single click. If an off-curve control point is moved for a Bezier component, then it's opposing control point in any adjacent Bezier component is moved in the opposite direction unless it is also selected or the Control key is held in (Command key on Mac). * Three new geometric primitives based on paths have been added to the engine and are available in the Geometries page inside the World Editor. They are called path tube, path extrusion, and path revolution. Each of these primitives can be created when a path is selected in the editor to define the shape of a tube, the base shape of an extrusion, or the lateral surface shape of a revolution. When creating a tube geometry, you drag out a disk representing the shape of the tube's cross section. When creating an extrusion or revolution, the drawing tools behave like a box and a cylinder, respectively so that you can create geometries with the shape of the path, but at any size. * A new effect type called a tube effect has been added to the engine. It is similar to the beam effect, except that it follows a path instead of a straight line. The tube effect is drawn as a circular disk representing the cross-sectional shape. The actual effect can only be seen in the perspective view with lighting turned on. * When a tube (geometry or effect), extrusion, or revolution is created, the path from which it was made is copied into the geometry or effect node so that the original path is not needed in order to rebuild the node (for example, with different subdivision settings). A link to the original path is also stored in a built-in connector of type PATH. When the original path is edited, the node linking to it will not be updated automatically, but any such node can be explicitly rebuilt using the linked path by choosing the Rebuild with New Path command under the Geometry menu. * Several improvements have been made to the in-game interface panels and the Panel Editor: ** It is now possible to create and register custom panel items. ** There is a new stock panel item that encapsulates editable text. ** The selection tool in the Panel Editor now functions as a box select tool once the cursor has been dragged a few pixels. The shift key can be used to add to the current selection when dragging out a box. ** It is now possible to modify settings for multiple items simultaneously in the Panel Editor. ** A new mutator called Animate has been implemented which plays frames of animation out of a texture by changing the texture coordinates of an image item. The mutator is configured by specifying the horizontal and vertical grid dimensions for subdividing the texture, the total number of frames, and the frame rate. * Script method registrations now take only a single name string instead of the two name strings previously taken. When a script method name is displayed in the Script Editor, lines will automatically be broken at a space, hyphen, or forward slash, if necessary, or at any newline character (represented by \n). * In the World Editor, the types of entities, locator markers, and reference markers are now displayed in the Info page for the node to which the gizmo is attached. * A new command called Bake Transform into Vertices has been added to the Geometry menu in the World Editor. This applies the node transform of a geometry node to each of its vertices, and then sets the node transform to the identity. * Another new command called Reposition Mesh Origin has been added to the Geometry menu. When this is selected, a dialog appears that lets you select min, center, or max for each of the three axes, where these refer to the bounding box. The node position for each selected mesh will be moved to the specified location, and the vertices of the mesh will be translated the same distance in the opposite direction. This has the effect of moving the object origin without actually moving the world-space vertex positions. * A new command called Move Viewport Camera to Node has been added to the Node menu. This command moves the camera in all perspective viewports to the position of the selected node and faces it along the node's z-axis. The camera still obeys the ordinary restrictions on the viewport camera, so it will not roll side to side or tilt up or down more than about 83 degrees from the horizontal. * Another new command called Open Referenced World has been added to the Node menu. This command opens the world resource referenced by each selected reference marker in a separate editor window. * A new camera speed slider has been added to the Viewports page in the World Editor. This controls the maximum speed of the free camera in the perspective viewports. * When the Invert Geometry command (Ctrl-Shift-I) is used in the World Editor to invert a primitive geometry node, it will now also flip the "Build inverted" flag from the Get Info dialog automatically. This will cause the geometry to continue rebuilding in the inverted state if it's altered at a later point in time. * When placing a locator marker in the World Editor, the marker will now keep the identity transform until the mouse has been dragged several pixels away from the click point. This prevents random rotations if the mouse is clicked and released at the same point. * The Markers page now displays a list of registered locator types. Selecting one of these lets you place a locator in the scene with the registered type already set. * The Memory Manager has been largely rewritten and there is an enormous performance improvement in general allocation speed. * Screenshots saved using the shot command are now saved as compressed TGA files (whereas before they were not compressed). * All interface elements now have common functions for getting and setting their sizes. These functions are <code>GetElementWidth()</code>, <code>GetElementHeight()</code>, and <code>SetElementSize()</code>. Also, the origin for the push button element is now at the left edge of the button at the vertical position for the button text. * When a radio button is selected by the user, it will now automatically unselect all other radio buttons having the same parent element. * It is no longer necessary to type the full path name when opening a world, texture, or sound using the command line. The top-level virtual directory name should be left off. * All resource names may now contain the names of system variables, and these will be replaced by the value of each variable before the Resource Manager tries to locate a resource. The syntax is ($name). For example, if you try to load a resource with the name textures/($season)/leaves, and the value of the variable $season is "summer", then the Resource Manager will load the resource named textures/summer/leaves. A resource name may contain any number of variable names. In any case when the right syntax isn't used or the variable doesn't exist, the resource name is not altered. * The Xcode projects for the Mac have been changed significantly. Everything now builds as a dynamic library instead of a bundle. The engine module also builds as a dynamic library because it's not possible to link against both an executable and another plugin on the Mac, and this is necessary for plugins that depend on other plugins. A small executable that contains only the main() function is now built as a wrapper for the engine module. ed317d2ea8a93fb629603ff5e55550af7457b2f4 Release Notes for Build 147 0 52 54 2023-07-15T09:53:22Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' February 25, 2008 * This release is primarily an update that contains the demo shown at GDC. * A new enemy character, the spider, has been added to the demo game. Its controller is now the simplest example of a controller for a non-player character. * A world can now be paused by setting the <code>kWorldPaused</code> flag with the <code>[http://c4engine.com/docs/WorldMgr/World_SetWorldFlags.html World::SetWorldFlags()]</code> function. (C..." wikitext text/x-wiki __NOTOC__ '''Release date:''' February 25, 2008 * This release is primarily an update that contains the demo shown at GDC. * A new enemy character, the spider, has been added to the demo game. Its controller is now the simplest example of a controller for a non-player character. * A world can now be paused by setting the <code>kWorldPaused</code> flag with the <code>[http://c4engine.com/docs/WorldMgr/World_SetWorldFlags.html World::SetWorldFlags()]</code> function. (Care should be taken to avoid clearing other flags by calling <code>[http://c4engine.com/docs/WorldMgr/World_GetWorldFlags.html World::GetWorldFlags()]</code> and logically ORing in the <code>kWorldPaused</code> flag.) While this flag is set, controllers and effects are not moved. The demo game now sets this flag when the menu window is displayed in single player mode. 770702e7c2c6f8500e0ae3b769f2fd4c3372ef88 Release Notes for Build 148 0 53 55 2023-07-15T09:54:27Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' March 13, 2008 * Glow and bloom effects have been added to the post-processing phase of the rendering system. No distinction is made between glow and bloom during post-processing, but the two effects are created by different parts of the shading equations. Glow comes from the emission component's alpha channel, and bloom is determined by the intensity of the specular component. Glow and bloom are enabled on a per-material basis, and each ha..." wikitext text/x-wiki __NOTOC__ '''Release date:''' March 13, 2008 * Glow and bloom effects have been added to the post-processing phase of the rendering system. No distinction is made between glow and bloom during post-processing, but the two effects are created by different parts of the shading equations. Glow comes from the emission component's alpha channel, and bloom is determined by the intensity of the specular component. Glow and bloom are enabled on a per-material basis, and each has a check box in the Material Manager. (Glow is found under the Ambient tab, and bloom is found under the Specular tab.) Glow and bloom can be enabled or disabled globally in the Graphics Settings dialog. * A new generic animation controller has been added to the engine. This controller can be attached to an entity node, and it simply plays an animation resource for that entity. The animation controller also exposes play and stop functions that can be called from a script to change animations or stop the current animation. * The Material Manager in the World Editor has been largely redesigned. It now always displays every material that is used by a world, and all previews are rendered in real-time. The various material attribute settings have been reorganized into four panes: Diffuse, Specular, Ambient, and Texcoords. The first three panes group attributes by where they appear in the lighting equations, and the Texcoords pane contains everything related to texture coordinate transforms and animation. The New button now creates an empty material, and a Duplicate button has been added that creates a copy of the currently selected material. A Delete button has been added that removes a material from a world, but only if it is not used by anything. The Import and Export buttons still exist and function as before. * The World Editor now directly supports plugin modules. The external API is in a rather early state, but it is possible to create a plugin that displays new tool pages in the editor. World Editor plugins should be placed inside the <code>Plugins/Tools/Editor/</code> directory so that they are loaded after the World Editor itself is loaded. Support for import and export plugins has been moved to the World Editor, and the Collada Importer plugin has been modified to work directly with the editor. * Up to four columns of tool pages can now be displayed in the World Editor. How many columns there are, and where they appear, is configured by selecting Editor Settings from the Layout menu. Each of the four available columns can be placed on the left or right side of the viewports when made visible. Pages can be dragged from one column to another. * By holding in the Control key (Command key on Mac) while clicking on the collapse or close button of a tool page, all pages in the same column can now be collapsed or closed at once. There is a new command in the Page menu that shows all available tool pages. * In the World Editor, the selection mask will now be automatically updated whenever a new node is drawn so that the node is always selectable right after it is created. * The Clone Group command in the World Editor has been replaced with the Clone command. Any node can be cloned now, and the result is a new copy of the node that refers to the same object(s). * The right-click popup menu in the World Editor now contains a Get Info item. Also, the Frame All and Frame Selection items in this menu now work on perspective viewports. * Editable text elements can now be made read-only by setting the <code>kEditableTextReadOnly</code> flag with the <code>SetEditableTextFlags()</code> function. Text can still be selected and copied from a read-only text element, but it cannot be modified by the user. * The Movies plugin now exposes script functions for playing, stopping, pausing, and resuming movie items inside panel effects. * The Collada Importer now correctly sets the default up direction to the y axis if an imported file does not indicate an up axis. e76266ec525bce6c1746ea31697c0035cff62574 Release Notes for Build 149 0 54 56 2023-07-15T09:55:11Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' July 8, 2008 * The graphical scripting system in the engine has been replaced with a far more powerful design that supports variables, loops, and conditional execution. All previously existing scripts will continue to run without modification. Details about the new scripting system are too extensive to include here, but they can be found in the [[Graphical Scripting Language]] article. * The <code>Function::Execute()</code> function now ta..." wikitext text/x-wiki __NOTOC__ '''Release date:''' July 8, 2008 * The graphical scripting system in the engine has been replaced with a far more powerful design that supports variables, loops, and conditional execution. All previously existing scripts will continue to run without modification. Details about the new scripting system are too extensive to include here, but they can be found in the [[Graphical Scripting Language]] article. * The <code>Function::Execute()</code> function now takes a pointer to the method that is calling it. This allows the function to set the method's boolean result value in the new scripting system. * The engine's texture format has been changed in this release. The file extension is still <code>.tex</code>, and the engine can still read the old format. However, in the next release, the old format will no longer be supported. We have included a conversion utility in this release that will scan your Data folder and convert all <code>.tex</code> files to the new format automatically. All textures that ship with the engine have already been converted. To use the conversion utility, run the engine and type <code>convtex</code> in the command console. This will convert all <code>.tex</code> files in your Data folder to the new format in place. '''Be sure that you have a backup copy of your custom textures before running this utility.''' * The Texture Viewer tool has been renamed to Texture Tool, and all the code that creates textures of any kind has been moved to this plugin. Generated textures (light projections, shadow maps, environment maps, and ambient spaces) are now made using the <code>gentex</code> console command. * The ambient space feature has been replaced with a new rendering method for static volumetric ambient occlusion. Ambient spaces are still placed in zones as they were previously, but now they only encode directional occlusion that modulates the ambient light intensity as opposed to encoding the ambient light intensity itself. More ambient lighting capabilities will be added to near-term future releases. * The <code>SceneImportPlugin</code> class has been changed slightly so that it's possible for an import plugin to display a dialog before importing a scene. (See the Collada import plugin for an example.) The <code>SceneImportPlugin::ImportGeometry()</code> function now takes a pointer to the editor window as a parameter, and the importer must call the <code>Editor::ImportScene()</code> function in order to complete the import. * The Collada importer now offers the option to attempt to import texture maps while it is importing a scene. When this option is turned on, any qualified diffuse map, normal map, gloss map, or emission map specified in a Collada file will be imported with the Texture Tool using the default settings. A texture map qualifies for import if its path name contains <code>/Import/</code> so that the importer recognizes it as being in the C4 Import folder. If the Collada file specifies the wrap modes for a texture map, then they are respected when a texture map is automatically imported. * A Cleanup button has been added to the Material Manager. Clicking this button causes all duplicate materials to be merged into one material. Materials are considered equivalent if they produce the same shaders. * The <code>Entity</code> class has been renamed to the <code>Model</code> class. To update your code, make the case-sensitive global replacements of Entity to Model and entity to model. This will have the effect of inadvertently changing the word "identity" as well, so you'll need to also make the replacement of dmodel to dentity to clean it up. * A new toggle button has been added to the World Editor that turns display of models on and off. Models are no longer displayed as a bounding box. * A model registration now takes one more parameter that specifies the human-readable model name to be displayed in the World Editor. * A new multi-zone referencing system has been implemented that generalizes some older techniques used in the engine for transition zones and effects that span multiple zones. Most of this system is internal to the engine and not exposed to higher-level code, but there's one new addition that game programmers need to be aware of. Model nodes have always automatically reparented themselves to the zones that contain them as they move around, but now when a model exits a zone, it also attaches a special reference to the zone that survives until the model's bounding volume has completely left the zone. This allows large models to span multiple zones and to be correctly identified by the visibility determination system. The whole thing is automated, so no code needs to be written to take advantage of this feature. * The <code>kEntityAttached</code> flag, previously used to signify that a model is attached to another model in some way, has been removed from the engine. The Model class now determines whether models are attached to other models automatically. * Under Windows, the Sound Manager now uses XAudio2 instead of DirectSound. This should be completely transparent to all higher-level code, but you will need to upgrade to the latest version of DirectX. The engine will only compile with the June 2008 DirectX SDK or later. * The streaming capabilities in the Sound Manager have been generalized so that it's possible to stream sound data from any kind of source. The method for setting up a streaming wave file has changed—see the [[Working with Sound]] article for more information. * A color scale and bias operation has been added to the post-processing pass. The <code>World::SetFinalColorTransform()</code> function can be used to specify a scale color S and a bias color B that are applied to the final rendered color C to yield SC + B. The red, green, and blue channels of these colors can be any floating-point values that produce the desired effect. The scale and bias colors only affect rendering of the current world and not the graphical user interface. * The <code>WorldRenderTask()</code> and <code>InterfaceRenderTask()</code> functions have been added to the Application class. These functions are called once per frame after the world has been rendered and after the graphical user interface has been rendered, respectively. * The Display Manager will now allow any window size to be specified by the <code>$displayWidth</code> and <code>$displayHeight</code> variables when running in windowed mode. * The Node class is now subclassed from Constructable so that custom node types can be defined and properly deserialized. The <code>[http://c4engine.com/docs/System/Constructable_InstallConstructor.html Constructable::InstallConstructor()]</code> function is used to install a callback function that constructs custom node subclasses. * Full native support for Xbox 360 controllers under Windows has been added to the Input Manager (using XInput). The demo game code has been updated so that it's possible to play using only the Xbox controller. Better support for DirectInput joysticks has also been added to the Input Manager. * The movies plugin now allows movies to be played as streams from remote locations. The movie controller and movie panel item now both have check boxes indicating whether the movie name is a URL. * Movie play position is now synchronized in multiplayer games when new players join. ef982debddff948911d76d22ad889e9b2c3301fb Release Notes for Version 1.4.10 0 55 57 2023-07-15T09:56:11Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' July 25, 2008 * A new cross-platform voice chat system has been added to the engine as the Audio Capture Manager. In a multiplayer game, audio can be captured on each player's machine, compressed using a variable bit-rate algorithm, and distributed through the server to the other players in the game. In the demo game, there are options for enabling or disabling sending and receiving of voice chat, and there's a volume control for received v..." wikitext text/x-wiki __NOTOC__ '''Release date:''' July 25, 2008 * A new cross-platform voice chat system has been added to the engine as the Audio Capture Manager. In a multiplayer game, audio can be captured on each player's machine, compressed using a variable bit-rate algorithm, and distributed through the server to the other players in the game. In the demo game, there are options for enabling or disabling sending and receiving of voice chat, and there's a volume control for received voice chat. * Each <code>[http://c4engine.com/docs/MessageMgr/Player.html Player]</code> object that corresponds to a player in a game is now part of a graph that represents the voice communication channels among all of the players. Voice chat is only sent from player A to player B if there exists a channel starting at player A and ending at player B. A channel is an edge in the player graph encapsulated by the <code>Channel</code> class. The demo game automatically establishes channels among all players who have enabled voice chat receipt, but more complex arrangements such as team chat can be set up. * It is now possible for a remote portal to span multiple zones so that a single large portal can be used in several zones in cases when a reflective or refractive surface is bigger than a single room. To use this functionality, just add a connector to each zone (other than the portal's owning zone) and link it to the remote portal. * The S3TC texture compression algorithm built into the engine has been significantly improved in this release, both in terms of image quality and speed. * Due to some serious limitations in Mac OS 10.4 (Tiger), we will only be supporting Mac OS 10.5 (Leopard) beginning with this release. The Mac project files now require Xcode 3. It's still possible to build the engine under earlier versions of Mac OS X, but it will require making your own project files for Xcode 2 and working around the dynamic loader limitations (for which one solution is to hard-code an absolute installation path for the C4.app bundle). 0337539d895d9651d29ab94b06a34df128ad4f0a Release Notes for Version 1.5 0 56 58 2023-07-15T09:57:00Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' December 27, 2008 * A new voxel terrain system has been added to the engine, along with several terrain editing tools in the World Editor. More information about these can be found in the [[Editing Terrain]] article. Support for the old terrain geometry has been removed from the engine, so any old terrain in existing worlds will disappear when opened in the new version of the engine. To preserve the old terrain, select it in the editor unde..." wikitext text/x-wiki __NOTOC__ '''Release date:''' December 27, 2008 * A new voxel terrain system has been added to the engine, along with several terrain editing tools in the World Editor. More information about these can be found in the [[Editing Terrain]] article. Support for the old terrain geometry has been removed from the engine, so any old terrain in existing worlds will disappear when opened in the new version of the engine. To preserve the old terrain, select it in the editor under a previous version and convert it to a generic mesh before opening it in the current version of the engine. * All of the shading systems in the engine have been completely replaced by a new architecture based on shader graphs. Every existing attribute-based material will continue to work just fine, but they are translated into shader graphs internally. The Material Manager still allows materials to be created by configuring a fixed set of material attributes, and this is still the preferred method of creating materials that only use the standard options. Arbitrary custom materials can now be created in the new Shader Editor that's accessible from the Material Manager window. * Both the new Shader Editor and the existing Script Editor have a new tool for creating sections in a graph. A section is simply a rectangular area drawn beneath the graph that can be used to group a set of nodes for organizational purposes&mdash;it has absolutely no effect on the function of the graph itself. Each section has a user-configurable title and background color that can be changed by double-clicking on the title bar or by selecting the section and choosing Get Info from the menu (or hitting Ctrl-I). * Three new script methods have been added that can be used to set scalar, vector, and color parameter values in shader-based materials. These methods allow you to specify a parameter slot number and a new parameter value. When executed, the methods search all of the materials on the target geometry node for Constant Scalar, Constant Vector, and Constant Color processes that use the parameter slot and change the input value for those processes to the new value specified in the script. * A new tool has been added to the Material page in the World Editor that works like the eyedropper in a painting program. When this tool is clicked on a geometry surface in a scene, the current material is set to the material used on that surface. * For transition zones having exactly two outgoing direct portals, the ambient light color is now dynamically calculated. The light color is simply a smooth gradient in between the two portals, blending from one zone's ambient light color to the other's. If either zone's ambient light color changes, then the gradient is automatically updated. * The collision system has been improved in this release. To gain the full benefits of these improvements, it is necessary to rebuild the collision data for geometry nodes in the World Editor. This can be done by selecting all of the geometry nodes, hitting Ctrl-I to open the Node Info window, moving to the Collision tab, and then just clicking OK. * The engine now recognizes the operating system clipboard under Windows and Mac OS X, so it's possible to copy and paste text between other applications and text boxes inside C4. * The project files now have a new build target called Server. When this target is selected, the engine builds without any graphics, sound, or input systems so that it can be run on minimal hardware and used as a dedicated server. * The <code>kWindowMaximize</code> flag can now be passed to the Window constructor to make it as large as possible upon creation. * If an attempt is made to read strings from a non-existent string table resource, the engine now returns the "<missing>" string in the same way that it already does for missing strings in an existing resource. * The Time Manager has been modified so that it correctly handles frame rates greater than 1000 fps. * The quad effect now has a setting for the blend mode that it's rendered with. * The Panel Controller script functions for getting and setting panel item text now work on editable text items as well as static text items. * New standard Panel Controller script functions have been added to get and set the texture map shown in an image item. * The script expression parser now recognizes the words "true" and "false" as boolean literals. These are now treated as keywords and cannot be used as variable names. * Hexadecimal integer literals using the <code>0x</code> syntax are now recognized by the script expression parser. * The box select tool in the World Editor has been reimplemented and is now very precise. * In the World Editor, double-clicking on a node in the scene graph now opens the Node Info window. * When importing a geometry node with the Collada Importer, if the transform contains any kind of scale, then the 3&times;3 portion of the transform (containing the scale and rotation) is now baked into the vertices. * A voice chat channel can now be enabled and disabled so that it's possible to switch among chat configurations without having to create and/or delete channels. * A new type of event handler, the <code>WindowEventHandler</code>, can now be installed in the Interface Manager to receive events pertaining to GUI windows. The types of events posted are (a) a window was added/removed from the GUI, (b) a window's enable or hidden state has changed, and (c) the mouse has moved into or out of a window's content area. * The Input Manager has been modified so that it is possible to receive raw input from only specific classes of devices while still receiving ordinary OS events for mouse and/or keyboard devices. The <code>kInputNormal</code> mode that could previously be passed to the <code>InputMgr::SetInputMode()</code> function has been replaced by the three values <code>kInputMouseActive</code>, <code>kInputKeyboardActive</code>, and <code>kInputGameActive</code>. The "Game" classification includes all devices that are not mice or keyboards. These values can be passed in any combination (through logical OR) to the <code>InputMgr::SetInputMode()</code> function to set the input mode for those classes of device. If either <code>kInputMouseActive</code> or <code>kInputKeyboardActive</code> is not specified, then you continue to receive OS events for those classes of device. The <code>kInputAllActive</code> value is provided to enable raw input for all devices, equivalent to the old value of <code>kInputNormal</code>. * The <code>SetAudioCaptureProc()</code> function has been added to the Audio Capture Manager. This function lets you install a callback procedure that is periodically invoked when new audio data has been captured on the local machine, and it provides a way for the application to intercept the raw sample data. * The configuration file <code>Engine/engine.cfg</code> has been renamed to <code>Engine/input.cfg</code> since it only includes commands for binding input controls. * In debug mode, the values used to fill newly allocated memory and just-deallocated memory have been changed to <code>0x7FCCCCCC</code> and <code>0x7FDDDDDD</code>, respectively. This was done so that any float-point values read from uninitialized memory would be interpreted as NaNs. In the case that a memory block is not a multiple of four bytes in size, <code>0xCC</code> and <code>0xDD</code> are used to fill in the remainder bytes. * In debug mode under Windows, the engine will now display an error message at startup if the working directory does not point to the location containing the Data directory. * The per-vertex fog option has been removed from the engine. Fog calculations are now always performed at the fragment level. * The separate specular color option has been removed from light objects. * The microfacet rendering variable <code>$renderMicrofacetShading</code> has been removed from the engine. Microfacet rendering can no longer be turned off through a flag. 4932c2e7f43770f4503e13b247a292fdeba33cc2 Release Notes for Version 1.5.1 0 57 59 2023-07-15T09:57:47Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' February 8, 2009 == Core Engine == === Terrain === * The shader code for terrain texturing has been enhanced for hardware supporting array textures (currently G80 and later). When texture array functionality is available, terrain now renders faster and at higher quality while also using less memory for the palette of terrain textures. Existing terrain palette textures must be re-imported before it's possible to take advantage of the new e..." wikitext text/x-wiki __NOTOC__ '''Release date:''' February 8, 2009 == Core Engine == === Terrain === * The shader code for terrain texturing has been enhanced for hardware supporting array textures (currently G80 and later). When texture array functionality is available, terrain now renders faster and at higher quality while also using less memory for the palette of terrain textures. Existing terrain palette textures must be re-imported before it's possible to take advantage of the new enhancements. * The method by which normal vectors for terrain geometries are calculated has been changed. Existing terrains can be updated by selecting all of the geometries in a block and choosing Rebuild Primitive from the Geometry menu in the World Editor. The shading on the terrain will change slightly when this is done because the normals are smoother in regions containing clusters of vertices. === Shaders === * The Round process has been added to the Shader Editor. It simply rounds numbers to the nearest integer. On hardware that does not explicitly support a round instruction, the round operation is replaced by an addition of 0.5 followed by the floor operation. === Miscellaneous === * A new manager has been added to the engine: the Job Manager. The Job Manager is designed to distribute work over the available processor cores so that the engine can utilize the full potential of multi-core CPUs. Work is submitted in the form of "jobs" representing a single task of some kind. Jobs will be used for both short tasks that take place every frame and longer tasks that run in the background. Various parts of the engine will start using the Job Manager over the next few releases. * New functions have been added to the <code>Player</code> class that let you get and set the volume for the voice chat associated with each player. * The log file format has been upgraded. It now shows more information about the current system on which the engine is running, and more information is given when errors occur. == Tools == === Collada Importer === * The Collada Importer will now recognize two sets of texture coordinates and import them. If there are two sets, then they are accessible as Texcoord 1 and Texcoord 2 in the Material Manager and the Shader Editor. 9a8d4ce7ca6e21d20b55155d763640bc6e106afc Release Notes for Version 1.5.2 0 58 60 2023-07-15T09:58:18Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' February 13, 2009 == Core Engine == === Terrain === * The method by which normal vectors for terrain geometries are calculated has been changed again. Existing terrains can be updated by selecting all of the geometries in a block and choosing Rebuild Primitive from the Geometry menu in the World Editor. * A new setting has been added to the Graphics Options dialog called "Use high-detail terrain textures". If this box is unchecked, then..." wikitext text/x-wiki __NOTOC__ '''Release date:''' February 13, 2009 == Core Engine == === Terrain === * The method by which normal vectors for terrain geometries are calculated has been changed again. Existing terrains can be updated by selecting all of the geometries in a block and choosing Rebuild Primitive from the Geometry menu in the World Editor. * A new setting has been added to the Graphics Options dialog called "Use high-detail terrain textures". If this box is unchecked, then terrain palettes having entries of size 1024&times;1024 or larger are reduced in resolution to one-half size. This box is unchecked by default on the Mac due to some driver issues with 4096&times;4096 textures. === Miscellaneous === * This release contains a few workarounds for driver bugs on ATI hardware and on the Mac. * Antialiasing is now enabled on ATI hardware because it works correctly in their latest drivers. * The S3TC compression algorithm has been improved a little bit in this release. Some textures will now compress with higher quality. * Texture array functionality is disabled on ATI hardware in this release, and this will continue to be the case until ATI supplies correctly working drivers. This only affects terrain texture palettes that were imported in version 1.5.1. == Tools == === Collada Importer === * The Collada Importer tool now imports camera nodes. Only perspective cameras are supported. 6b870a07888dcc3eb52c0d149464f92e628d39a5 Release Notes for Version 1.5.5 0 59 61 2023-07-15T09:58:59Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' March 21, 2009 == Core Engine == === Scripts === * A new standard script method called "Get String Length" has been added to retrieve the length of a string. Ordinarily, a script variable would be fed into the method's "Input string" setting. The method outputs an integer. === Miscellaneous === * The skin controller now performs skinning updates as a Job Manager task. The allows multiple models to be skinned in parallel on multi-core CP..." wikitext text/x-wiki __NOTOC__ '''Release date:''' March 21, 2009 == Core Engine == === Scripts === * A new standard script method called "Get String Length" has been added to retrieve the length of a string. Ordinarily, a script variable would be fed into the method's "Input string" setting. The method outputs an integer. === Miscellaneous === * The skin controller now performs skinning updates as a Job Manager task. The allows multiple models to be skinned in parallel on multi-core CPUs. * Depth lights no longer have a constant shadow map boundary. Instead, the boundary is calculated dynamically based on the bounding volumes in the scene being illuminated. The default method for calculating the boundary is conservative, so an optimally-sized box usually won't be calculated automatically. However, you can draw a shadow space volume (in the Spaces page) and connect the light's SHAD connector to it in order to force the light to assume a particular bounding box for the volume it illuminates. The whole point of this is that a depth light's position is no longer relevant for shadow mapping. Only the direction in which the light faces matters. * The post-processing pipeline can now accept a full color matrix to be applied to the final scene, enabling a wider range of special effects. The color matrix is set using the <code>[http://c4engine.com/docs/WorldMgr/World_SetFinalColorTransform.html World::SetFinalColorTransform()]</code> function. == Tools == === World Editor === * Several visual improvements have been made in the World Editor: ** All types of nodes are now rendered in the perspective viewport (zones and groups being the only ones that weren't before). ** The volumes for triggers, emitters, spaces, physics shapes, and effects now display text on their surfaces describing the type of object for easier identification. ** Lights, sources, and cameras now display a volume similar to the other volumetric nodes, but only when selected. ** Infinite lights are now rendered with a big arrow showing the direction of illumination. ** Portals now show arrows indicating the direction in which they flow. ** Markers, models, lights, sources, cameras, and particle systems are now displayed as crosshairs with an icon attached off-center. Previously, the cubic icon would block out the background making alignment difficult. ** Groups are now rendered as loose bounding boxes. * The gizmo in the World Editor now displays three new handles, colored red, green, and blue, when the rotation tool is selected. These handles can be used to rotate a node about its local axes, where red, green, and blue correspond to ''x'', ''y'', and ''z''. * Selection locking has been added to the World Editor. While the selection is locked, a tiny lock icon appears next to the cursor to indicate that the selection can't be changed. 3efee0b8c76ed99695fe43a52f76ce2509930f2c Release Notes for Version 1.5.8 0 60 62 2023-07-15T09:59:35Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' April 4, 2009 == Core Engine == === Shaders === * A new "Shader Time" process has been added to the Shader Editor. It outputs the engine's internal shader timer, which has a period of 120 seconds. The time output in the shader is normalized to the range [0,1]. === Miscellaneous === * The skinning code has been modified in this release to allow normals and tangents to be skinned instead of calculated separately. New performance optimiza..." wikitext text/x-wiki __NOTOC__ '''Release date:''' April 4, 2009 == Core Engine == === Shaders === * A new "Shader Time" process has been added to the Shader Editor. It outputs the engine's internal shader timer, which has a period of 120 seconds. The time output in the shader is normalized to the range [0,1]. === Miscellaneous === * The skinning code has been modified in this release to allow normals and tangents to be skinned instead of calculated separately. New performance optimizations have also been implemented for skinned models. To use these new capabilities, an existing model must be either be re-imported or have the Recalculate Normals command applied to its geometries in the World Editor. * Fluid and cloth simulation now run as multithreaded tasks through the Job Manager. * A perspective exclusion mask can now be specified for portals. This allows you to disable portals from specific camera perspectives, such as when rendering to the refraction buffer. == Tools == === World Editor === * The Models page in the World Editor now contains a tool for placing generic unregistered models. After a generic model has been placed in the scene, the model resource is specified under the Model tab in the Node Info window. When multiple instances of the same generic model exist in the scene, they share the same object data. However, if a registered model is placed in the scene, and the same model resource is specified for a generic model as well, then they do not share the same object data. That is, copies of registered models all share each other's data, and copies of generic models all share each other's data, but there's no sharing between registered and generic models. Therefore, you should be consistent in what method you use to place a particular model in the scene. If a model is registered with the engine (and thus appears in the list of registered models), it is always better to use the registered model than to use a generic model. * The Terrain page now contains a smoothing brush. When this brush is used to draw on terrain, it applies a simple 3D blur filter to the underlying voxel field. * The World Editor now adds a new command to the global Tools menu called "Reopen Played World", with the shortcut Ctrl-Shift-P. This menu item unloads the currently playing world and reopens the World Editor with the last world that was played by typing Ctrl-P. * The range of speeds possible for the free camera in the World Editor has been increased on both the slow and fast ends. 25c9425f8d352949a9656b1bd52c23dbccf169a1 Release Notes for Version 1.5.9 0 61 63 2023-07-15T10:00:20Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' April 28, 2009 == Core Engine == === Shaders === * The Expand process has been added to the engine. It multiplies the input by 2.0 and then subtracts 1.0. This is useful for expanding values from the [0,1] range to the [−1,1] range. (Note that the Normal Map process already implicitly expands the values read from its texture, so it's not necessary to use an Expand process after a normal map is read.) === Scripts === * A new Set Ex..." wikitext text/x-wiki __NOTOC__ '''Release date:''' April 28, 2009 == Core Engine == === Shaders === * The Expand process has been added to the engine. It multiplies the input by 2.0 and then subtracts 1.0. This is useful for expanding values from the [0,1] range to the [−1,1] range. (Note that the Normal Map process already implicitly expands the values read from its texture, so it's not necessary to use an Expand process after a normal map is read.) === Scripts === * A new Set External Variable method has been added to the Basic tab in the Script Editor. This method can set the value of an object-scope variable in another script to the value of any local variable belonging to the script that is running. === Miscellaneous === * Bone nodes in a model are now identified by a hash value derived from the bone's name instead of an index number based on the bone's position within the model. What this means is that any skinned mesh can be copied from one skeleton and pasted onto another skeleton as long as the bones that it needs exist in the new skeleton. There is no longer any requirement that the two skeletons have the same number of bones or that they occur in the same order within the skeletal hierarchy. * Normal maps can now be compressed using ordinary S3TC when the alpha channel is unused (which disqualifies parallax maps). Compressed normal maps only contain information in the green and alpha channels of the texture after they've been imported. These provide an 8-bit ''x'' component and a 6-bit ''y'' component for each normal vector, and the ''z'' component is reconstituted in a slightly more expensive fragment program. * A new <code>ShockwaveEffect</code> class has been added to the engine, and it produces an expanding distortion ring in the scene. This effect is implemented in the Extras plugin module, and the <code>ShellEffect</code> class has also been moved to the Extras plugin. * The <code>kControllerLocal</code> flag can now be specified by a controller to indicate that it operates autonomously and does not need to receive messages from remote machines. This flag would ordinarily be set in the controller's <code>Preprocess()</code> function before calling the base class's <code>Preprocess()</code> function, and it prevents the controller from being added to the world's controller array or being assigned a controller index. * With this release, official support for PowerPC-based Macs has been discontinued. However, the engine still builds and runs just fine on PowerPC processors. 46107a119906d4d3fbd9de4a7cf29302d1b07893 Release Notes for Version 2.0 0 62 64 2023-07-15T10:02:00Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' May 31, 2010 == Core Engine == === Physics === * This release contains the first version of the native C4 physics architecture. The native physics processing is enabled in a particular world by placing a special "physics node" anywhere in the root zone. The physics node has a physics controller attached to it for which global properties such as the acceleration of gravity can be adjusted. If a world does not contain a physics node in its..." wikitext text/x-wiki __NOTOC__ '''Release date:''' May 31, 2010 == Core Engine == === Physics === * This release contains the first version of the native C4 physics architecture. The native physics processing is enabled in a particular world by placing a special "physics node" anywhere in the root zone. The physics node has a physics controller attached to it for which global properties such as the acceleration of gravity can be adjusted. If a world does not contain a physics node in its root zone, then the native C4 physics is completely dormant when that world is played. This allows third-party physics libraries to be used with absolutely no extra cost to bypass the native physics. * A physics object is created by assigning a rigid body controller to a node and creating one or more "shapes" as subnodes of that node. The shapes define the volume occupied by the physics object as seen by the physics simulation, and they are always fixed relative to each other within a single object. Each shape can have a different density, and the engine automatically calculates properties such as the center of mass and the inertia tensor. * Rigid bodies can be connected by "joints" to other rigid bodies or to the static environment. Six types of joints are currently defined: spherical, universal, discal, revolute, cylindrical, and prismatic. * A new node type called a "field" has been added to the engine, and it represents a volume inside of which a force can be applied to physics objects. Forces are applied to objects in a field through the extensible <code>[http://c4engine.com/docs/PhysicsMgr/Force.html Force]</code> class. After a field has been created in the World Editor, a force can be assigned to that field in the Node Info window. In this release, there are two forces built into the engine, a fluid force and a wind force. The fluid force applies buoyancy and drag, and it can be configured to simulate a current. The wind force applies air drag for a wind current. Custom forces can be defined by creating subclasses of <code>Force</code> and registering them with the engine. * A basic mover controller is provided by the engine. This controller moves a rigid body from point A to point B (and handles the reverse direction, too) under script control. This controller can be used to implement things like simple elevators. === Terrain === * The voxel terrain system now includes a seamless geomip level-of-detail algorithm that is the product of a large R&D project at Terathon. As terrain is edited, the engine automatically creates lower-resolution terrain geometries and arranges all of the terrain geometry nodes in an octree structure. When terrain is rendered, special polygons are inserted along the boundaries between terrain geometries of different resolutions to produce a smooth transition from high-resolution to lower-resolution meshes. Since voxel terrain is inherently volumetric, this kind of linkage between neighboring meshes can get very complicated, and it was necessary to develop a new algorithm to produce a robust result with real-time performance. * The terrain-specific shading capabilities of the engine have been modified in this release, partially to accommodate the new terrain LOD system. The four six-sided texture cubes used to specify texture palette entries have been replaced by two sets of three textures, with the three entries in each set representing the (a) up direction, (b) down direction, and (c) all horizontal directions. * Existing terrains need to be converted in order to retain their previous texture settings and blending information. To convert a terrain block, select all of the terrain geometries in the editor and press Ctrl-R to rebuild them. (The easiest way to select all of the terrain geometries is to select one geometry, press Ctrl-Up-Arrow to select the parent block, and then press Ctrl-Down-Arrow to select all of the block's subnodes.) Some texturing capabilities in the previous version do not translate perfectly into the new scheme, so it's possible that parts of the terrain will have textures different from what they had before. In these cases, it will be necessary to manually paint new materials onto those areas to update the textures. * The Terrain Texture and Terrain Normal shader processes have been extended so that custom blending of terrain materials is possible. By default, these processes fetch colors from both the primary and secondary terrain textures (where each fetch really represents a triplanar texture blend) and then blends them together using the blend data from the terrain mesh. A new setting has been added that lets you turn off blending and only fetch either the primary or secondary texture. You can then blend the textures any way you want. The default blend is given by a linear interpolation of the primary and secondary textures using the blue component of the vertex color as the interpolation parameter. * The terrain material painting capabilities have been expanded in this release. Materials can now be specified on a per-voxel basis instead of a per-geometry basis, and the per-voxel blending state has been decoupled from the material IDs. There are now two paint brushes in the editor: one that modifies the blend values, and another that only modifies the materials. There is also a check box that enables material replacement when using any of the other terrain tools. * The engine can now use a special terrain palette texture resource that references a set of separate 2D texture map resources. This allows many different palettes to share textures from a (possibly large) pool of plain 2D texture maps, and it removes the need to store terrain palettes in two different formats for hardware compatibility. When a terrain palette texture map is loaded, it loads all of the texture maps that it references and assembles them into the optimal format for the available hardware. === Shaders === * A new shader process called Kill Fragment has been added to the engine. This process can accept one or two scalar inputs, and if the first input is less than the second input, then the current fragment is not rendered. If the second input is omitted, then it is assumed to be zero. This process can be used as a substitute for alpha testing when the alpha output needs to be used for something else like transparency, glow, or bloom. * A new shader process called Magnitude 3D has been added to the engine. This process takes the dot product of an input vector with itself and outputs the square root of the result. * A new shader process called Front Normal has been added to the engine. This process takes a normal vector as input and negates its ''z'' component if the ''z'' component of the tangent-space light direction is negative. This is useful when rendering two-sided triangles with a normal map because it has the effect of always facing the normal vector to the front with respect to the light direction. * The second input for the Set if Less Than and Set if Greater Equal shader processes has been made optional. If the second input is omitted, then it is assumed to be zero. === Scripts === * A new built-in script method called Terminate External Script has been added to the engine. This method causes all instances of a script running on another node to be terminated immediately. * A new built-in script method called Get Script Time has been added to the engine. This method outputs the time that has elapsed since a script began running. === Miscellaneous === * Support for Unicode text rendering and input has been implemented throughout the engine. Strings are always encoded in UTF-8, and thus ordinary ASCII strings are not affected. The String Importer tool will properly handle any text encoded as UTF-8. The Font Generator tool has been rewritten to support the entire Basic Multilingual Plane of the Unicode Standard. See [[Generating a Font]]. * Tablet support has been added to both the Windows and Mac version of C4. Stylus pressure is now taken into consideration when drawing with the terrain sculpting tools. * A new type of light source called a "Landscape Light" has been added to the engine. This light type is an infinite light that provides large-scale multiresolution shadow mapping capabilities, enabling shadow maps to be used over areas of unlimited size. The engine smoothly transitions from one resolution to another at adjustable distances from the camera. * A new flag called "Render at infinity" has been added to the Quad Effect. This causes the quad to be rendered infinitely far away in the direction of the quad's local ''z''-axis. This is useful for placing objects in the sky. * In order to be directly compatible with the new physics system, all velocities pertaining to sounds are now measured in meters per second by default. This applies to <code>Sound</code> objects, <code>Source</code> nodes, and the listener. * The remote portal node and camera panel item now have a minimum detail level setting. When the engine renders through one of these, the minimum detail level specifies the highest LOD that can be rendered for any particular geometry. The default value is 0, meaning that any LOD can be rendered. Setting the value to a higher number means that only LODs with that index or higher (which have lower detail) can be rendered. This is useful for decreasing the amount of processing that takes place when rendering things like reflections and refractions. * The velocity-depth-gradient buffer used by the motion blur effect has been changed to 16-bit floating-point color. This allows the higher-quality post-processing effect to be applied at any distance from the camera, and it will open up several new possibilities for other types of effects in future releases. * The <code>wire</code> console command has been extended so that you can specify whether wireframe lines are depth tested. The command <code>wire 2</code> turns on wireframe with depth testing, the command <code>wire 1</code> turns on wireframe without depth testing, and the command <code>wire 0</code> turns off wireframe. The <code>wire</code> command by itself still toggles the current wireframe state on or off, and depth testing retains it previous state. * The <code>Lock</code> class has been added to the system utilities. The class implements a read/write lock that can be simultaneously acquired by multiple threads for shared access to some object or acquired by a single thread for exclusive access to the object. * The <code>Model</code> class no longer owns the root animator assigned to it. The animator tree must be released by the code belonging to the class that creates it. * Primitive geometries now triangulate disks with a pattern that is more efficient for rasterization. This change affects the disk, cylinder, cone, truncated cone, dome, path tube, and path revolution primitives. * Resource names in PAK files are no longer case sensitive. * PAK files now take precedence in reverse lexicographical order. That is, if the same resource appears in the file <code>Patch1.pak</code> and <code>Patch2.pak</code>, then the one in <code>Patch2.pak</code> is guaranteed to be the one that gets loaded. * Files that are written by the engine, such as config files, the log, and saved games, are now stored in special directories designated by the operating system as places where these kinds of files should be stored. Under Windows, the config files variables.cfg and input.cfg are stored in the user's roaming application data directory, and the C4Log.html file is stored in the user's non-roaming application data directory. Saved games and screenshots are stored in the user's documents directory. In all cases, the files are stored in a subdirectory having the name of the application. Under Mac OS X, all of these files are stored in the <code>~/Library/Application Support/&lt;application name&gt;/</code> directory. * The engine contains a new mechanism that prevents game and plugin modules built for a different target from being loaded by the engine. For example, if the engine has been built for the Optimized target, it will fail to load any modules built for the Debug target. The operating system's dynamic linker won't be able to find a target-specific symbol, and that will cause it to fail and display an error message. The engine will continue running after such a failure, but the module won't be available. * A new plugin named Logitech has been added to the engine, and it manages devices made by Logitech that are capable of displaying an image on an LCD screen such as the G15 keyboard. * The <code>natural</code> and <code>unsigned_natural</code> types have been renamed to <code>machine_int</code> and <code>unsigned_machine_int</code> so that it's more clear what their purpose is. This is also more consistent with the naming of the <code>machine_address</code> type. The shorthand <code>machine</code> and <code>unsigned_machine</code> can also be used in a way analogous to using <code>long</code> instead of <code>long int</code> in C. (A <code>machine_int</code> is an integer at least 32 bits wide, but is wider as necessary for an arithmetic instruction to be executed without an extra sign extension instruction. Currently a <code>machine_int</code> is 32 bits wide on x86 processors. On 64-bit PowerPC processors, a <code>machine_int</code> is 64 bits wide.) * The <code>engine</code> macro has been renamed to <code>C4API</code>. The <code>module_export</code> and <code>module_import</code> macros have been renamed to <code>C4MODULEEXPORT</code> and <code>C4MODULEIMPORT</code>. The <code>extras_api</code>, <code>movie_api</code>, <code>editor_api</code>, and <code>texture_api</code> macros have been renamed to <code>C4EXTRASAPI</code>, <code>C4MOVIEAPI</code>, <code>C4EDITORAPI</code>, and <code>C4TEXTUREAPI</code>. * The underlying code for panel items has been replaced with a new hierarchy of <code>Widget</code> classes. These will be the same classes that will replace the <code>Element</code> classes in a future version so that ordinary GUIs and panel effects both use the same unified architecture. == Tools == === World Editor === * A new terrain painting tool has been added that creates holes in the terrain mesh. This is useful for creating entrances to structures embedded in the terrain without having to laboriously dig out large caverns. Holes are indicated by a special material ID, so painting an ordinary material over a hole will restore the terrain surface. * A new terrain sculpting tool called the "Slope brush" has been added that draws conical shapes whose sides are defined by one of several slope functions. The maximum radius of the terrain brushes has also been increased to allow much larger areas of terrain to be sculpted in a single brush stroke. * A new command called "Optimize Terrain" has been added to the Geometry menu. This command simplifies the selected terrain meshes, removing the tiny and very thin triangles that are commonly produced by the marching cubes algorithm. Triangle counts tend to decrease by about 25% when applying this optimization. * A new command called "Generate Ambient Occlusion" has been added to the Geometry menu. This command calculates a static per-vertex alpha value that represents the amount of ambient light that reaches the surface at each vertex. In order to be effective, geometries must be tessellated densely enough so that the sample values are close enough together to look good. Terrain naturally has sufficient vertex density, but ambient occlusion data can be generated for any kind of geometry. * The per-vertex ambient occlusion is not rendered until the new "Use vertex ambient occlusion" flag is set for the materials used on a geometry having ambient occlusion data. The ambient light values are also available to shaders as the alpha component of the vertex color. The shader system automatically accounts for ambient occlusion, so it is not necessary to explicitly perform the occlusion calculation in a shader. * The reference marker tool has been moved to its own page called "Worlds", and a list of referenced worlds has been added. The list shows which worlds are referenced by the current world, and selecting one lets you place a reference marker for that world in the scene with a single click. The generic reference marker tool is used to place references to new worlds that had not previously been referenced in the current world. * A popup menu with several commands pertaining to reference markers is also available in the Worlds page. The Cleanup command removes worlds that are no longer referenced from the world list. (Upon opening an existing world in this version, the Cleanup command can be used to populate the world list with the worlds that are already referenced.) The Select All command can be used to select all reference markers in the scene that refer to the world currently highlighted in the worlds list. The Select Some command can be used to randomly select a given percentage of those reference markers. Finally, the Replace Selected command changes the selected reference markers so that they refer to the currently highlighted world. * A new page called "Placement" has been added. This page contains some settings that can be applied when new nodes are placed in a scene through the perspective viewport. If placement modifications are enabled, then the new node can be rotated randomly about the <i>z</i>-axis, aligned to the tangent plane at the placement point, and/or sunk into uneven ground so that the base of the node is automatically moved below the ground surface. These settings are useful for placing foliage on terrain, and more settings will probably be added in future releases. * An "Occlusion Space" node has been added to the Spaces page. The occlusion space acts like a box-shaped occlusion portal and blocks all nodes behind its outline on the screen from being rendered. Occlusion spaces should be embedded in large solid objects to help with visibility culling. An occlusion space is disabled whenever the camera enters its box volume. * Viewport caching has been implemented. This provides much better responsiveness when working with large, complex scenes. * The Node Info window now remembers which tab was last visited, and it will return to that tab by default the next time the Node Info window is opened (if the tab exists for the selected nodes). * Right-clicking in the perspective viewport now engages the free camera tool. The contextual menu can still be accessed by holding in Control (Command on the Mac) when right-clicking. * Holding in the Shift key while using the free camera tool now causes the camera speed to be multiplied by 5. * It is now possible to click on nodes belonging to external models and referenced worlds, and doing so selects the model node or reference marker node to which the clicked-on node belongs. When a model node or reference marker node is selected, geometries belonging to the model or referenced world are drawn with a gray wireframe as well. * Node types that have no size associated with them, such as markers, models, skyboxes, and physics joints, can now be placed in a world within the scene graph viewport. When one of the tools used to create these types of node is active, clicking on a node in the scene graph viewport causes a new node of the type represented by the current tool to be created as a subnode of the node that was clicked. The new node's transform is the identity, so its position and orientation coincides with those of its super node. * A new command called "Edit Script or Panel" has been added to the Node menu. This is a shortcut for going straight to the Script Editor or Panel Editor when a node with a script controller attached to it or a panel effect is selected. These editors are also still accessible from the Controller tab in the Node Info window. * The Mesh Tools page has been removed, and the Select Surface tool now appears at the top of the editor window. * Fog can now be disabled for a skybox by checking the "Do not apply fog" box under the Skybox tab in the Node Info window. * The terrain builder can now import RAW voxel data that has been exported from another application. A RAW file should contain an array of floating-point values stored in little endian byte order, and the size of the array should be equal to the product of the width, height, and depth of the voxel map. To be compatible with some other applications, the ''z'' coordinate varies the fastest, followed by the ''y'' coordinate, and finally the ''x'' coordinate. The importer can treat either +''y'' or +''z'' as the up direction. === Texture Tool === * The texture importer tool can now remember the settings that were used to import each particular texture map. A new check box called "Remember settings" has been added to the texture import dialog, and it is checked by default. When checked, the settings used to import the texture are written to a CFG file alongside the input TGA file in the Import folder. The next time the texture is imported, the information in this file is used to initialize the settings in the import dialog. The CFG file can also be used as a standalone command line that can be executed using the <code>import</code> console command. * When a texture currently in use is re-imported, the texture is now automatically reloaded by the engine. This only works properly if the type (2D, Rect, Cube) of the texture stays the same. * A new check box called "Bleed colors for alpha test" has been added to the texture importer tool. When this box is checked, pixels having an alpha value less than 0.75 (where less than 0.5 fails the alpha test) pick up the color from the nearest pixel that passes the alpha test, up to a maximum of 16 pixels away. This process helps remove borders that can appear when alpha-tested textures are rendered. The command-line option for this setting is <code>-bleed</code>. * The <code>texpal</code> command has been added for creating reference-based terrain palettes. See [[Creating a Terrain Palette]]. === Collada Importer === * There are two new options exposed by the Collada Importer plugin. First, imported materials can be merged with materials already existing in the scene if they are identical. Second, an existing material in the scene can be used instead of an imported material if the names match. f8fa266123c9025c4f2e3db3070939b9591aeced Release Notes for Version 2.1 0 63 65 2023-07-15T10:02:44Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' July 8, 2010 == Core Engine == === Graphics === * A new impostor system has been added to the engine for rendering large numbers of objects such as trees. ** Impostor images are pre-generated for an object for 8 directions (every 45 degrees) about the vertical axis. When rendered, two images are noise-blended in a small transition range between two 45-degree sectors to avoid popping. ** There is a transition region inside which the real o..." wikitext text/x-wiki __NOTOC__ '''Release date:''' July 8, 2010 == Core Engine == === Graphics === * A new impostor system has been added to the engine for rendering large numbers of objects such as trees. ** Impostor images are pre-generated for an object for 8 directions (every 45 degrees) about the vertical axis. When rendered, two images are noise-blended in a small transition range between two 45-degree sectors to avoid popping. ** There is a transition region inside which the real object and the impostor are noise-blended to avoid popping. ** An impostor has a normal map that encodes polygon orientation so that shading can be made to match the real object. ** An impostor has a depth channel so that received shadows don't appear streaked across the flat quad on which they are rendered. ** An impostor has a special shadow mapping texture that encodes depth and masking information for 4 elevation angles. This allows an impostor to cast good shadows, including onto itself. ** You can generate additional images for use in the impostor shader. For some trees, these could include things like a gloss map and transmission map. * Some problems that previously occurred when separate fog spaces were used in the direct perspective and in the refraction perspective simultaneously have been eliminated. These fog spaces no longer interfere with each other. * There is a new flag for skyboxes that smears the texture maps below the horizon. This allows you to use a texture that is only half as high as it is wide for the four horizontal directions, but still render the skybox geometry below the horizon. === Physics === * The controller functions for the mover controller wait for the mover to reach the beginning or ending position now before they allow a script to continue. * The rigid body controller now has a setting for rolling resistance. A positive value causes a rolling object to gradually slow down. Rigid bodies also have new external linear and angular resistance values. === Interface === * Widgets and mutators can now be identified with a string of up to 15 characters in length. This is a replacement for the four-character codes that had previously been used. When loading an existing world, four-character identifiers for widgets and mutators are automatically converted to strings in the objects themselves and in any script methods that refer to them. === Miscellaneous === * A new observable object class has been added to the utility library along with an associated observer class. These are now used for passing events from objects to a group of listeners. The <code>Observable</code> class replaces the previously-existing <code>Triggerable</code> class, which has now been removed from the engine. == Tools == === Collada Importer === * The Collada Importer now imports vertex colors if they are present on a mesh. Inside C4, the vertex color can be accessed using the Vertex Color interpolant process in the [[Using the Shader Editor | Shader Editor]]. 2438aa8be4b41b871f478ce0073803b8b330a6e7 Release Notes for Version 2.1.1 0 64 66 2023-07-15T10:03:21Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' September 20, 2010 == Core Engine == === Graphics === * A new material flag called "Use alpha multisample coverage" has been added. This turns on transparency antialiasing when a multisampled rendering context is being used. Alpha multisample coverage can be used to soften up the outlines of alpha-tested materials. * A global light detail level has been added to the engine. Any light source can now specify a detail level, and the light w..." wikitext text/x-wiki __NOTOC__ '''Release date:''' September 20, 2010 == Core Engine == === Graphics === * A new material flag called "Use alpha multisample coverage" has been added. This turns on transparency antialiasing when a multisampled rendering context is being used. Alpha multisample coverage can be used to soften up the outlines of alpha-tested materials. * A global light detail level has been added to the engine. Any light source can now specify a detail level, and the light will only be rendered if the global detail level setting is at least as high as that specified by the light source. This is useful for turning off dynamic lights for things like projectiles on lower-end hardware. * The method for determining the default graphics settings has been rewritten. There are three general initial quality settings, and one is chosen based on the number in the name of the graphics card. If the second digit is 5 or less, then the lowest quality setting is used. If the second digit is 6 or 7, then the normal quality setting is used. If the second digit is 8 or 9, then the highest quality setting is used. All of this only matters if the user hasn't yet changed any graphics settings, creating a new <code>variables.cfg</code> file. === Terrain === * The scale for triplanar texture coordinates has been made an independent parameter in the material object settings. It used to share the scale for texcoord 0, but this interferes with the use of ordinary 2D textures on the terrain. Materials for existing terrains will need to be updated if the texcoord scale is anything other than the default 1/16. === Physics === * New code has been added for collision detection between shapes and arbitrary geometry meshes, and the continuous collision detection code has been completely replaced. Performance has improved drastically. * The <code>RigidBodyContact</code> class contains a new function called <code>[http://c4engine.com/docs/PhysicsMgr/RigidBodyContact_GetWorldContactPosition.html GetWorldContactPosition()]</code> that can be used to simplify the extraction of world-space contact information in a consistent manner. * A new Truncated Dome shape has been added to the engine. Like the other truncated shapes, this is a dome with its top cut off by a plane parallel to its base. * Problems that arose in previous versions when multiple shapes were used for a single rigid body have been corrected. * The amount of collision data stored in a world file for most types of geometry has been reduced considerably. To update existing worlds, select all and then select Rebuild Geometry from the Geometry menu (or just type Ctrl-A followed by Ctrl-R). Be sure to make a backup copy of your worlds first. === World Manager === * A new <code>[http://c4engine.com/c4engine/doco/WorldMgr/Modifier.html Modifier]</code> class has been added to the engine, and one or more of them can be attached to reference markers in order to modify the appearance or structure of the referenced world in some way. This allows some variation among different instances of a referenced world while still preserving the data-sharing benefits. In this release, there are three built-in modifier types, and a game module can define its own custom modifiers. === Miscellaneous === * The variable <code>$applicName</code> has been removed from the engine as the method for identifying the name of the game module to load. The engine now determines the name of the game module through the following steps, in this order: # If the symbol <code>GAME_MODULE_NAME</code> is defined (in the project properties), then its value is used as the name of the game module. The symbol should begin and end with double quotes, so to load the SimpleBall game, you would define <code>GAME_MODULE_NAME</code> to be <code>"SimpleBall"</code>, with the quotes. # If the symbol <code>GAME_MODULE_NAME</code> is not defined, then the engine checks to see if the variable <code>$gameModuleName</code> exists, possibly because it was defined on the command line. If this variable exists, then its value is used as the name of the game module to load. # If the <code>$gameModuleName</code> doesn't yet exist, then the engine executes the file <code>game.cfg</code>, which can be stored in any subfolder of the <code>Data</code> folder or in a PAK file. This file should define the variable <code>$gameModuleName</code> by assigning the name of the game module to it. For example, to load the SimpleBall game, the <code>game.cfg</code> file would contain the line <code>$gameModuleName = "SimpleBall";</code>. # If the <code>$gameModuleName</code> variable still isn't defined, either because <code>game.cfg</code> doesn't exist or it didn't define the variable <code>$gameModuleName</code>, then the name of the game module defaults to <code>Game</code>. * A generic lossless data compression algorithm has been added to the engine, and it is now used for all texture resources. Most textures will get smaller if they are re-imported, but all existing textures will continue to work just fine (re-importing is not required). * Backwards compatibility with releases preceding version 1.4.10 has been removed. 289ee879ffb2a7abfe53b1ec9919b8543562ee59 Release Notes for Version 2.1.2 0 65 67 2023-07-15T10:03:57Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' September 27, 2010 == Core Engine == * This release is primarily a tuning update. Several miscellaneous performance and robustness improvements have been made throughout the engine. == Tools == === Collada Importer === * The Collada importer now removes degenerate triangles when a mesh is imported. (A degenerate triangle is one for which at least two vertices have exactly the same position.) == Tutorials == * The Hell's Mouth and Lost..." wikitext text/x-wiki __NOTOC__ '''Release date:''' September 27, 2010 == Core Engine == * This release is primarily a tuning update. Several miscellaneous performance and robustness improvements have been made throughout the engine. == Tools == === Collada Importer === * The Collada importer now removes degenerate triangles when a mesh is imported. (A degenerate triangle is one for which at least two vertices have exactly the same position.) == Tutorials == * The Hell's Mouth and Lost Cemetery worlds are now available in the <code>Data/Demo/world/</code> directory so they can be opened in the World Editor. 1a9f0860a391ec47462672979617071f14dbcbdf Release Notes for Version 2.5 0 66 68 2023-07-15T10:04:43Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' February 12, 2011 == Core Engine == === Interface Manager === * The systems for rendering on-screen interfaces and in-game panel effects have been unified into a single architecture that uses the <code>[http://c4engine.com/docs/InterfaceMgr/Widget.html Widget]</code> class hierarchy. The <code>Element</code> class hierarchy has been removed from the engine, and there is now a <code>Widget</code> subclass corresponding to each <code>Elemen..." wikitext text/x-wiki __NOTOC__ '''Release date:''' February 12, 2011 == Core Engine == === Interface Manager === * The systems for rendering on-screen interfaces and in-game panel effects have been unified into a single architecture that uses the <code>[http://c4engine.com/docs/InterfaceMgr/Widget.html Widget]</code> class hierarchy. The <code>Element</code> class hierarchy has been removed from the engine, and there is now a <code>Widget</code> subclass corresponding to each <code>Element</code> subclass that previously existed. The functionality in many of the new <code>Widget</code> subclasses has been enhanced compared to the corresponding <code>Element</code> subclass. * Several new types of widgets have been added that have no <code>Element</code> counterpart. These are the line, border, password, text button, and hyperlink widgets. * A new type of resource, the panel resource with extension <code>.pan</code>, has been defined for holding interface layouts. A panel resource can be loaded under any widget, so it may contain an entire window's layout or just smaller sections. * The Interface Manager now displays a "strip" at the bottom of the screen that is similar to the Windows task bar. Certain types of windows have buttons associated with them in the strip so that it's easy to switch among multiple editors (for example). The Tools menu that was previously displayed in a menu bar at the top of the screen is now accessible from the C4 button displayed at the left end of the strip, and there is no global menu bar. (Menu bars are now contained inside windows.) * Any widget can have a help balloon assigned to it that either displays a text message or loads an entire panel resource. * The Interface Manager now starts in manual input management mode. A call to the <code>InterfaceMgr::SetInputManagementMode()</code> function is necessary if you want the input devices to automatically switch to gameplay (active) mode when all interactive windows are closed. * Some functionality for widget animation (including color changes for things like hover events) have been deferred to the next release because the design of the system that was going to handle this has been expanded. === Graphics === * New object-space and world-space vertex position interpolants have been exposed in the Shader Editor. * The subdivisions setting has been removed from the skybox node. Each of the six faces of a skybox is now always rendered as one quad. * The engine now uses the Nvidia API to detect the driver version, and it disables the <code>GL_EXT_direct_state_access</code> extension automatically if old drivers known to be buggy are installed. === Physics === * All collision detection code in the physics system now runs as a set of jobs so that it can take advantage of all available CPU cores. * Shapes now have a flag that causes them to be ignored for collision detection, but still lets them affect the mass distribution of a rigid body. A shape with this flag set would typically be put inside another shape to weight an object down in a certain place. * The cloth controller has been upgraded to work with the new physics system. Cloth now uses the global gravity acceleration stored in the physics controller attached to the physics node for a world. Cloth is also affected by wind force fields. * An &ldquo;exclusive&rdquo; flag can now be set for force fields. This prevents the field from being applied to all rigid bodies globally. Instead, an exclusive field must be explicitly used by a controller designed to recognize a force field to which its target node is connected. The cloth controller recognizes a <code>WIND</code> connector on its target node and applies the wind generated by any wind force field to which it's connected. (So a cloth geometry can be connected to an exclusive wind force field in order to receive the wind without anything else being affected.) * A new gravity force type has been added to the physics system so that force fields that modify the global gravity can be created. * The <code>kRigidBodyLocalSimulation</code> has been added for rigid bodies. If set, then the rigid body is only simulated on the local machine, and the server does not transmit information about the rigid body to the clients. This is useful for debris objects that only exist for a short time and have no effect on gameplay if they're simulated differently on different machines. === Math Library === * A new high-performance function called <code>Math::CosSin()</code> has been added for calculating sine and cosine simultaneously for the same angle. It returns a <code>Vector2D</code> object with the cosine in the <code>x</code> coordinate and the sine in the <code>y</code> coordinate. === Utility Library === * The <code>InsertReplace()</code> function has been added to the <code>Map</code> class. This inserts an element into the map and replaces any existing element with the same key that is already in the map. * The <code>HashTable</code> class now guarantees that elements having the same key are stored consecutively. This lets you iterate through all elements having the same key by finding the first element and then calling <code>Next()</code> until the key changes or no elements are left. === System Utilities === * Support for 3Dconnexion devices (like SpaceNavigator) has been implemented in the engine. Multiaxis mouse movement is currently supported in the World Editor. * The <code>OpenExternalWebBrowser()</code> function has been added to the <code>Engine</code> class. This launches the default web browser and goes to the specified URL. This function works on all platforms supported by the engine, but it can take 10 seconds or more to execute under Windows XP. * The engine can now switch among game DLLs without restarting. When the value of the <code>$gameModuleName</code> system variable changes, the current application object is destroyed, the game DLL is unloaded, and a new game DLL is loaded and initialized. == Tools == * The Panel Editor has gained a number of new capabilities that include a transform type-in, nudge tools, alignment functions, and grouping functions. * The Panel Editor, Script Editor, Shader Editor, and Model Viewer now use the page system for organizing tools and information on the left side of their windows. * The Texture Importer can now apply S3TC compression to externally-created normal maps. If the "Treat RGB channels as vector" box and "Use S3TC compression" box are both checked, then the red channel is copied to the alpha channel, and then the red and blue channels are cleared to zero before the texture is compressed. (This is the format expected by the shaders when a compressed normal map is used.) * The &ldquo;Bleed colors for alpha test&rdquo; setting in the Texture Importer now also increases alpha values by 50% for each mipmap level. This has the effect of preventing thin features in alpha-tested textures from vanishing as the geometry to which they're applied gets farther away from the camera. * There is a new option when importing animations that freezes the model's root node to its current position. == Tutorials == * Trigger activation has been added to the SimpleChar game. 00b58a631b16bd13c18812876df576428687a2a1 Release Notes for Version 2.5.1 0 67 69 2023-07-15T10:05:37Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' February 14, 2011 == Core Engine == === Interface Manager === * The list widget now allows items to be inactivated so that they can't be selected. A list item is made inactive by setting the <code>kWidgetInactive</code> bit with the <code>[http://c4engine.com/docs/InterfaceMgr/Widget_SetWidgetState.html SetWidgetState()]</code> function. === System Utilities === * Support for non-English keyboards has been significantly improved under W..." wikitext text/x-wiki __NOTOC__ '''Release date:''' February 14, 2011 == Core Engine == === Interface Manager === * The list widget now allows items to be inactivated so that they can't be selected. A list item is made inactive by setting the <code>kWidgetInactive</code> bit with the <code>[http://c4engine.com/docs/InterfaceMgr/Widget_SetWidgetState.html SetWidgetState()]</code> function. === System Utilities === * Support for non-English keyboards has been significantly improved under Windows. The engine explicitly recognizes dead keys now when typing accented letters. The key used to open the console is now always the key below the Escape key, and not necessarily the key for the accent grave. === Math Library === * The <code>Asin()</code> and <code>Acos()</code> functions now clamp their arguments to the range [&minus;1.0, 1.0] so that input values outside the domain of the inverse sine and inverse cosine functions don't generate NaNs. === Physics === * Fields can now be disabled so that they don't apply any forces. * Fixed a problem where the wrong transform would be applied to a mover when it reached the beginning or ending position. This only happened if the mover target was not in the root zone. == Tools == * Several stability improvements have been made to the Panel Editor. 09d71b76efafe1a5d93c6a6d8213ac3ad7db59c9 Release Notes for Version 2.5.2 0 68 70 2023-07-15T10:06:11Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' March 1, 2011 == Core Engine == === System Utilities === * Additional support for foreign keyboards has been implemented. * The function registered for a mouse event handler must now return a boolean value indicating whether it handled the event. Like the keyboard event handlers, a mouse event handler function will only be called if the preceding event handler returned <code>false</code>. === World Manager === * Corrected a situation i..." wikitext text/x-wiki __NOTOC__ '''Release date:''' March 1, 2011 == Core Engine == === System Utilities === * Additional support for foreign keyboards has been implemented. * The function registered for a mouse event handler must now return a boolean value indicating whether it handled the event. Like the keyboard event handlers, a mouse event handler function will only be called if the preceding event handler returned <code>false</code>. === World Manager === * Corrected a situation in which unused materials in a world could be temporarily loaded when the world is played. == Plugins == === Movies Plugin === * Fixed a problem that would prevent movies from playing in user interface windows. == Tools == === World Editor === * Fixed a problem that could cause skinned models to appear incorrectly in the World Editor. == Tutorials == * Added a start window interface to the SimpleBall tutorial. 93e42c625d115886ef307347cdaf659fe405b58f Release Notes for Version 2.5.5 0 69 71 2023-07-15T10:06:45Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' April 14, 2011 == Core Engine == === Graphics === * The shadow mapping capabilities used by the landscape light have been redesigned. There is no longer any restriction on geometry size relative to the section sizes for a landscape light. This allows smaller section sizes closer to the camera, which produce higher-resolution shadow maps, without having to worry about objects spanning more than two consecutive sections. * The timer query..." wikitext text/x-wiki __NOTOC__ '''Release date:''' April 14, 2011 == Core Engine == === Graphics === * The shadow mapping capabilities used by the landscape light have been redesigned. There is no longer any restriction on geometry size relative to the section sizes for a landscape light. This allows smaller section sizes closer to the camera, which produce higher-resolution shadow maps, without having to worry about objects spanning more than two consecutive sections. * The timer query mechanism (for timing on the GPU) has been reworked to prevent a decrease in performance that could previously occur when the Rate window was open. === Interface Manager === * Many of the <code>Widget</code> subclasses now expose settings for the colors of the different parts of the widgets, such as the background color, border color, highlight color, etc. Each widget has a default color type that usually corresponds to one of the more specific color types, and most widgets also support one or more additional color types. Some color types can have default values that are read from system variables, and these have a check box next to them in the settings. If the box is not checked, then the default color is used. * The Get Widget Color and Set Widget Color controller functions (accessible from the Call Controller Function script method) can now target any of the color types support by a widget. * Two new built-in controller functions, Get Widget Value and Set Widget Value, have been added to the scripting system. These can get and set values for the check, radio, progress, slider, scroll, list, multipane, and popup menu widgets. * The Pulsate and Fade mutators can now target any of the color types supported by a widget. * The Pulsate mutator now supports three blend modes: interpolate (the default), add, and multiply. The interpolate mode smoothly interpolates between the widget color ''c''<sub>1</sub> and the pulsate color ''c''<sub>2</sub> based on the time parameter ''t'', where ''t'' is always in the range 0 to 1. The resulting color is ''c''<sub>1</sub> * (1 - ''t'') + ''c''<sub>2</sub> * ''t'', and this is the same effect that the pulsate mutator had in earlier versions. The add mode causes the pulsate color to be fractionally added to the widget color, producing the color ''c''<sub>1</sub> + ''c''<sub>2</sub> * ''t''. The multiply mode causes the widget color to be multiplied by the smooth interpolation between white and the pulsate color to produce ''c''<sub>1</sub> * (white * (1 - ''t'') + ''c''<sub>2</sub> * ''t''). === Effects === * The marking effect has a new flag called <code>kMarkingDepthWrite</code> that enables writing to the depth buffer for a marking. This was previously always on if the <code>kMarkingLight</code> flag was specified, but now needs to be specified separately in order for a marking to modify the depth buffer. === Math Library === * The <code>GetSineTable()</code> and <code>GetCosineTable()</code> functions have been replaced by a single <code>GetTrigTable()</code> function. This table is an array of <code>Vector2D</code> objects for which the <i>x</i> component contains the cosine and the <i>y</i> component contains the sine of the array index times 2&pi;/256. === World Manager === * The <code>Block</code> class has been renamed to the <code>TerrainBlock</code> class. This was done because there will be a <code>WaterBlock</code> class in a future release. == Tools == === Collada Importer === * The Collada Importer is now able to handle more cases in which joint nodes (bones) are not properly indicated by the exporter that wrote a <code>DAE</code> file. * Extra functionality has been added to the Collada Importer to prevent the fusion of vertices with opposing tangent vectors, but with otherwise identical positions and texture coordinates. d8128b91cf1e009879f63d0e30759cc2d94c44c2 Release Notes for Version 2.6 0 70 72 2023-07-15T10:07:48Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' July 14, 2011 * '''IMPORTANT:''' In this version, some backwards compatibility with old versions of the engine has been removed. If you have problems with old world files in version 2.6, then please open those files in version 2.5.5 and save them in the World Editor before opening them in version 2.6 again. Be sure to backup your data first. == Core Engine == * A special flag named <code>C4FASTBUILD</code> has been added at the top of the..." wikitext text/x-wiki __NOTOC__ '''Release date:''' July 14, 2011 * '''IMPORTANT:''' In this version, some backwards compatibility with old versions of the engine has been removed. If you have problems with old world files in version 2.6, then please open those files in version 2.5.5 and save them in the World Editor before opening them in version 2.6 again. Be sure to backup your data first. == Core Engine == * A special flag named <code>C4FASTBUILD</code> has been added at the top of the file <code>C4PrefixWindows.h</code>. If this symbol is defined to be nonzero, then all of the projects are built using custom minimal header files for all Win32, DirectX, OpenGL, math library, and intrinsic functions. This greatly reduces build times at the slight risk of forward compatibility issues, but those are easily fixed. The default value of <code>C4FASTBUILD</code> is 1. If you experience problems compiling, then change it to 0. The <code>C4FASTBUILD</code> flag does not affect the linking stage. * The Stats window has been expanded and now has three tabs named Render, World, and Physics that display information for the Graphics Manager, the World Manager, and the Physics Manager. === Physics === * A new large-scale water surface simulation system has been added to the engine. Its intended use is for bodies of water ranging in size from small ponds to large oceans, and it is designed to simulate dynamic surface waves in an interactive manner. A body of water is represented in the scene graph by a new water block node that organizes a large number of water geometry nodes in a manner similar to how a terrain block node organizes a bunch of terrain geometries. Each water geometry simulates waves occurring within its bounds, and waves automatically propagate from one water geometry to its neighbors (if they exist). A water block can optionally include special "horizon" water geometries that extend a very large (but still finite) distance from the main water area. Waves are not simulated on horizon water geometries&mdash;they are intended to be shown only in the distance where the camera would never be close enough to see a dynamic water surface. * Water simulation for an entire water block is managed by a single water controller that is assigned to the water block. Settings for this controller allow you to specify parameters such as wave speed and fluid viscosity. The water controller automatically determines which water geometries need to be simulated based on proximity to the camera and time since they were last rendered, and inactive water geometries are put into a sleep state that consumes no processing time. * Waves are created by attaching wave generator objects to a water controller. Each wave generator creates a disturbance in the water surface that is then propagated by the water simulation. There are currently three types of wave generator, a point generator, a line generator, and a random generator. The point wave generator creates a circular disturbance around a single point, the line wave generator creates a disturbance around a line segment between two points, and the random wave generator adds random noise to the water. Wave generators typically exist for a short amount of time (measured in the number of simulation steps) and can be used for things such as creating a disturbance when an object falls into the water or creating a wake for a ship moving through the water. * Two new controller functions have been added for the water controller so that point and line wave generators can be created from a script. These functions allow a script to create disturbances in a water simulation at specific locations. * The fluid force field can now be connected to a water block so that the actual water surface elevation can be used in buoyancy calculations. This is done by connecting the field node to a water block and then specifying the connector key in the settings for the fluid force assigned to the field node. When a fluid force field is connected to a water block, the top of the field volume no longer represents the water surface, but is used only to determine whether the force affects rigid bodies that intersect the field. The water surface is determined completely by the water block in this case, and the top of the field volume should be extended high enough to include rigid bodies that could be floating on the largest waves existing in the water block. === Graphics === * A new shader process called Steep Parameter has been added to the shading system. This is just a convenience process similar to the existing Smooth Parameter process, and it calculates 2''t''&nbsp;&minus;&nbsp;''t''<sup>2</sup>. === Effects === * The <code>MarkingData</code> structure passed to the <code>MarkingEffect::New()</code> function now holds a scale and offset for the texture coordinates. This allows multiple distinct marking textures to be stored in the same texture map. * A setting called "interaction padding" has been added to panel effects. This padding controls how far away from the boundary of a panel effect the user needs to move the cursor before the panel will disengage. Setting this to a nonzero value helps avoid quick disengaging/re-engaging that can happen if the cursor moves slightly out of bounds for a moment. === World Manager === * The internal way in which node connectors work has been redesigned. Connectors now form a graph with hubs attached to the nodes that take part in the graph, and it's now possible to iterate over incoming connectors as well as outgoing connectors. For most users, these changes will have no visible effect&mdash;the functions used to link connectors are the same, and the World Editor tools have not changed. * There is a new modifier for reference markers that links a connector on the marker to a named node in the referenced world when it is loaded. * A shadow map can now be shared between the scenes rendered in the refraction buffer and the primary buffer. This happens automatically when a single shadow map is rendered through a remote portal that targets the refraction buffer ''unless'' the new "Render separate shadow map" box is checked for the portal. * There is a new setting for remote portals that lets you specify a different clear color for scenes rendered to the reflection or refraction buffer. This is useful for specifying a clear color for underwater parts of a scene that is different from the main clear color use for the above-water parts. * Remote portals also have a new "Portal plane offset" setting that moves the portal clipping plane outward by the specified distance for the purposes of rendering. This is useful when a remote portal is used to render refractions for water that has waves because it ensures that geometry up to the specified distance above the water plane is included in the refraction rendering. * A remote portal can now be configured so that only infinitely distant parts of the scene are rendered through it. This currently means that only the skybox is rendered through a remote portal with this flag set. * Skyboxes have a new option that specifies a vertical texture coordinate adjustment for the four sides of the box that cross the horizon. This can be used to cause the bottom of the textures to dip below the horizon a little bit. === Time Manager === * The <code>DeferredEvent</code> class has been renamed to <code>DeferredTask</code>, and the behavior has changed a little bit. A deferred task is now fired exactly one time and then automatically removed from the Time Manager's task list, so it won't keep firing every frame once it has been triggered, and there's no need to explicitly remove it from the task list. === System Utilities === * The Job Manager now supports job batches, and it's possible to block the main thread and wait for an entire batch to finish instead of waiting for each individual job separately. * There is a new static <code>SetReservedProcessorCount()</code> function in the <code>JobMgr</code> class that can be used to reduce the number of worker threads created by the Job Manager. This function must be called in the <code>WinMain()</code> or <code>main()</code> function before the <code>Engine::New()</code> function is called, or it will have no effect. === Math Library === * New classes called <code>Integer2D</code>, <code>Integer3D</code>, <code>Fixed2D</code>, and <code>Fixed3D</code> have been added to the engine for two- and three-dimension integer and fixed-point vectors. The <code>Point</code> class has been removed in favor of <code>Integer2D</code>, and the <code>Coordinates</code> class has been removed in favor of <code>Fixed3D</code>. == Plugins == === Browser Plugin === * There is a new browser plugin (for both Windows and Mac OS X) that defines a browser widget. A browser widget can be placed in windows or in-game panel effects just like any other widget, and it renders and interacts with web pages using Awesomium. * Several controller functions have been added to control browser widgets. These functions are able to navigate forward and back, navigate to a particular hard-coded address or to an address held in a text-based widget, reload the current page, or stop loading the current page. === Movies Plugin === * The movie widget has a new setting that enables alpha blending using the alpha channel in the movie itself. == Tools == === World Editor === * A new Water page has been added to the editor, and it includes a tool for drawing water blocks. When a water block is drawn, a dialog appears in which different settings pertaining to the resolution of the water surface can be specified. This dialog also lets you specify whether horizon water geometries are created in the east, west, north, and south directions. * The popup menu in the Water page includes a command for generating land height data. This command generates land height and gradient information at every vertex for each selected water geometry, and this information is available to shaders so that various effects can be created based on the depth of the water and the direction in which the land is sloping at every point. * The Optimize Terrain and Resize Terrain Block commands have been removed from the Geometry menu. These commands can now be accessed from a menu button in the top-right corner of the Terrain tool page. * New bulldozer tools have been added to the Terrain tool page. These tools tend to level out the ground where they are applied, one tool in an additive manner and one tool in a subtractive manner. A bias slider has also been added that can cause the bulldozer to tend to slope upward or downward. * A fuzziness slider has been added to the Terrain tool page, and it affects the texture blending paint brushes. Higher fuzziness means softer edges where textures blend together. The blend tool has also been split into two blend tools, one for painting the primary texture and another for painting the secondary texture. * A button has been added to the Placement page that causes the placement modifier settings to be applied to the current selection. This causes placement modifiers to be applied to selected referenced worlds, models, and locator markers regardless of whether the placement modifiers are enabled for newly created nodes. * The material pickup tool can now be used to grab the material from a skybox or impostor node by clicking on them in the scene graph viewport. === Texture Importer === * A new option in the texture importer can apply a layer of haze to skybox textures with the appropriate warping along the horizon. * New options have been added to the texture importer to scale texture maps to one-half resolution. One option scales the whole texture, and this can be useful if the original source image is larger and more detailed than necessary for the game. The other option scales only the horizon maps that can be generated when a normal map is imported, and this saves a lot of space without a significant decrease in quality because the shadows cast by horizon maps are generally soft. === Collada Importer === * Some new workarounds have been added to the Collada Importer in order to support illegal XML formats written by some exporters. bf22d0e01714652fae3b94272efb87fba028f502 Release Notes for Version 2.7 0 71 73 2023-07-15T10:08:33Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' September 30, 2011 '''IMPORTANT:''' The model animation format has changed in this version of the engine, and all animation resources (with the <code>.anm</code> extension) must be converted to the new format before they can be used. To convert your animations, run version 2.7 of the engine, open the command console, and type <code>convert</code>. This will automatically convert all of the animation resources in your entire <code>Data</code..." wikitext text/x-wiki __NOTOC__ '''Release date:''' September 30, 2011 '''IMPORTANT:''' The model animation format has changed in this version of the engine, and all animation resources (with the <code>.anm</code> extension) must be converted to the new format before they can be used. To convert your animations, run version 2.7 of the engine, open the command console, and type <code>convert</code>. This will automatically convert all of the animation resources in your entire <code>Data</code> folder. Be sure to backup your data before running the conversion utility in case something goes wrong. == Core Engine == === Graphics === * A new material format has been introduced so that materials can be loaded from resources by the engine. The new resource format uses the <code>.mtl</code> extension, and the previous format that used the <code>.mat</code> extension is now obsolete. A material can be loaded from a resource by calling the <code>MaterialObject::Get()</code> function. * The concept of ''substances'' has been added to the engine. A substance represents the composition of an object, such as wood or metal, and it can be used in a game to provide different effects when interacting with objects made of different substances. Any material object or physics shape can have a substance type assigned to it, and this type can be retrieved alongside the data for a collision. An application can register any number of substances with the engine by creating <code>Substance</code> objects, and then these appear in the World Editor. * The motion blur postprocessing effect has been modified so that the blur is lessened for small velocities. This makes the image sharper when the camera is moving slowly, and it prevents sudden blurring when the camera starts moving from a stationary position. === Physics === * The accuracy of collision detection with generic meshes (including terrain) has been improved significantly. * Physics shapes can now have a negative density. This can be useful for removing volume from a hollow or open object. Shapes with negative densities never participate in collision detection. === Effects === * The particle system functionality previously all contained in the <code>ParticleSystem</code> class has been split into several subclasses named <code>PointParticleSystem</code>, <code>InfinitePointParticleSystem</code>, <code>LineParticleSystem</code>, <code>QuadParticleSystem</code>, <code>PolyboardParticleSystem</code>, <code>FireParticleSystem</code>, and <code>BlobParticleSystem</code>. Any subclass that previously inherited directly from the <code>ParticleSystem</code> class needs to be changed so that it inherits from one of these new subclasses (and care should be taken to call base-class functions such as <code>Preprocess()</code> for these subclasses instead of <code>ParticleSystem</code>). The particle style has been removed from the constructors because it is no longer needed. * A new type of particle system supporting animated texture coordinates has been added through the <code>TexcoordPointParticleSystem</code>. This particle system uses the extended particle structure <code>TexcoordParticle</code> to hold a scale and offset for each particle that is applied to the texture coordinates. * A new voxel-based blob particle system has been added to the engine. Particles in a blob system are individual ellipsoids that merge together when they are in contact with each other to form larger complex blobs, and they are rendered as fully-lit triangle meshes. The triangle meshes are generated by a finely-tuned fixed-polarity marching cubes implementation that uses the Job Manager and island determination to distribute its work across all available processor cores. * A new flag called <code>kMarkingClipRange</code> has been added to marking effects. Setting this flag lets you specify the range of depths, with respect to the center and normal direction of the marking, to which the marking is clipped independently from the marking's radius. * The separate marking effect nodes created for a single surface marking can now be grouped into a new <code>MarkingList</code> container. This makes it possible to iterate over the pieces of a single surface marking, to delete an entire surface marking, and to be notified when all pieces of a single surface marking have been destroyed. * The obsolete fluid geometry and fluid controller classes have been removed from the engine. === World Manager === * Referenced worlds containing other referenced worlds are now supported four levels deep. * Two new built-in modifiers have been added to the engine, and they are called "Remove Lights" and "Remove Sources". These prevent light nodes and source nodes from being copied into the referenced world instances to which the modifiers are applied. === Animation System === * An animation is now bound to a model's nodes when the animation is used, as opposed to when it is imported. This means that the arrangement of nodes within a model can change without it being necessary to re-import any animations that have already been imported for the model. This feature only works with animations that are imported with version 2.7 or later. (The extra information needed to implement this feature is not added when animations are converted from an earlier version.) * Animation resources can now contain cue tracks, and the <code>FrameAnimator</code> class can be observed for cue events. A cue event is simply a 32-bit identifier that gets reported to the observer when a playing animation passes a cue's time value. The game code can handle cue events to do things like play sounds, apply damage, or trigger separate actions. === Job Manager === * A job can now determine which worker thread it is running in by calling the <code>Job::GetThreadIndex()</code> function. * The Job Manager has a new <code>Batch</code> class that can hold many jobs that need to finish as a group. The <code>JobMgr::JobMgr::FinishBatch()</code> function efficiently blocks the calling thread until all of the jobs in a batch have completed their work. * The <code>SetReservedProcessorCount()</code> function has been added to the Job Manager. It can be called before the Job Manager is initialized to reduce the number of worker threads created for processing jobs. === Scripts === * Character literals can now be used in Expression methods. A character literal is a sequence of one to four characters enclosed in single quotes. === Math Library === * New faster versions of the <code>Floor()</code> and <code>Ceil()</code> functions have been implemented. There are also new functions called <code>PositiveFloor()</code>, <code>NegativeFloor()</code>, <code>PositiveCeil()</code>, and <code>NegativeCeil()</code> that are faster if the input value is known to be positive or negative (but both work properly with an input of zero as well). The functions <code>FloorCeil()</code>, <code>PositiveFloorCeil()</code>, and <code>NegativeFloorCeil()</code> functions calculate both the floor and ceiling of the input in about half the time of calling floor and ceiling functions separately. * The <code>CosSin()</code> function has been moved out of the <code>Math</code> namespace and into the enclosing <code>C4</code> namespace. == Plugins == === Browser Plugin === * The Browser Plugin has been updated to work with Awesomium version 1.6.2. The plugin will no longer work with earlier versions of Awesomium. == Tools == === Model Viewer === * The Model Viewer now displays a cue track below the animation slider. A cue can be inserted, deleted, and edited for the frame at which the animation is currently stopped. Cues can be dragged to change their locations. After cues have been inserted or changed, the animation resource can be saved with the cue track by selecting "Save animation" from the Model menu or typing Ctrl-S (Cmd-S on the Mac). === Collada Importer === * The Collada Importer can now import splines, and they are turned into path nodes in C4. Only B&eacute;zier splines are supported at this time. f16ef54a4085d9668ea92da92b88d027d2a8834f Release Notes for Version 2.7.1 0 72 74 2023-07-15T10:09:12Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' November 14, 2011 == Core Engine == * A workaround has been implemented for a shadow trashing bug in the AMD graphics drivers that occurs mainly on Radeon HD 4xxx GPUs. * A problem related to wheel sensitivity on certain mice has been fixed. * A problem that caused geometries rendered as decals to not be completely opaque has been fixed. * A bug in the cylinder trigger detection code has been fixed. == Tools == * A new <code>Preproces..." wikitext text/x-wiki __NOTOC__ '''Release date:''' November 14, 2011 == Core Engine == * A workaround has been implemented for a shadow trashing bug in the AMD graphics drivers that occurs mainly on Radeon HD 4xxx GPUs. * A problem related to wheel sensitivity on certain mice has been fixed. * A problem that caused geometries rendered as decals to not be completely opaque has been fixed. * A bug in the cylinder trigger detection code has been fixed. == Tools == * A new <code>Preprocess()</code> function has been added to the <code>EditorPlugin</code> class in addition to the existing <code>Initialize()</code> function. These functions are called at different times during the construction of a new editor window to allow plugins to perform initialization tasks. Custom pages should always be created and added to the editor window in the <code>Initialize()</code> function. Any code that needs access to the scene data must be placed in the <code>Preprocess()</code> function. * A bug has been fixed in the Panel Editor that prevented hidden or locked widgets inside groups from being unhidden or unlocked. 0e49dde77dbe65e5ac27f2c9e07874f456c01606 Release Notes for Version 2.8 0 73 75 2023-07-15T10:09:50Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' April 17, 2012 == Core Engine == * The config file <code>variables.cfg</code> is now named <code>engine.cfg</code>. This change was made because the file can now store more information than just the values of the system variables. === Graphics === * The velocity-depth-gradient buffer has been given the new name "structure buffer", and there is a new option in the Graphics Manager called <code>kRenderOptionStructureEffects</code>. If eith..." wikitext text/x-wiki __NOTOC__ '''Release date:''' April 17, 2012 == Core Engine == * The config file <code>variables.cfg</code> is now named <code>engine.cfg</code>. This change was made because the file can now store more information than just the values of the system variables. === Graphics === * The velocity-depth-gradient buffer has been given the new name "structure buffer", and there is a new option in the Graphics Manager called <code>kRenderOptionStructureEffects</code>. If either <code>kRenderOptionStructureEffects</code> or <code>kRenderOptionMotionBlur</code> is present, then the structure buffer is available for use by shaders and by post-processing. * There is a new shader process called Delta Depth that can be used to obtain the scaled difference between the linear depth of the pixel being shaded and the linear depth stored in the structure buffer, clamped to [0,1]. This is useful for implementing things like soft particles. * There is a new shader process called Linear Ramp that remaps a range of a given width centered around a specific value to the range [0,1] and saturates. * There are new shader processes called Paint Texcoord and Paint Texture that can be used to sample from the paint space associated with the object being rendered. (See description of paint spaces below.) * A new flag called "Enable per-sample shading" has been added to materials. On hardware that supports it, this turns on the ability to run the fragment shader for each sample position, which can be used to antialias edges produced by the alpha test. If "Enable per-sample shading" and "Use alpha multisample coverage" are both enabled (and the hardware supports sample shading), then alpha multisample coverage is disabled. * Support for the <code>WGL_EXT_swap_control_tear</code> extension has been implemented. If the display flag <code>kDisplayRefreshSync</code> (renamed from <code>kDisplayVerticalSync</code>) is set, then framebuffer swapping is synchronized with the monitor's refresh cycle. If the display flag <code>kDisplaySyncTear</code> is set in addition, then the synchronization only occurs when the frame rate is high enough to beat the next refresh, and otherwise, an unsynchronized swap takes place immediately after a frame is finished rendering. === World Manager === * The visibility hierarchy and transform hierarchy have been decoupled. The transform tree still exists in the same form that it always has and corresponds to the node/subnode relationships. The visibility system now uses a new DAG structure on a hierarchical grid with fixed cell sizes inside each zone. Nodes are inserted into this DAG automatically by the engine. * The infinite zone now has a special bounding box that is used to define the maximum extents of the visibility graph with that zone. This box should be resized in worlds with large outdoor areas in the infinite zone so that the box encloses all static nodes other than terrain and water. The default box size is 1&times;1&times;1, but the benefits of the visibility graph don't kick in until it's at least 16&nbsp;m wide in either the ''x'' or ''y'' directions. Nodes outside the box will still be visible, but they won't be part of the visibility DAG. Subzones are not affected by the infinite zone's bounding box. * A new feature called "paint spaces" has been implemented, and these allow 2D painting canvases to be placed in a world. Each painting canvas holds a 1-, 2-, or 4-channel texture map, and this texture is projected onto all of the geometries that are associated with the paint space. A paint space has its own texture coordinate system that is independent of any geometry. The texture coordinates and texture map itself are accessed through the new Paint Texcoord and Paint Texture shader processes. Paint spaces can be used to hand paint details onto geometries for a multitude of purposes. (See description of painting tools below.) * The <code>ReferenceMarker</code> class has been renamed to <code>Instance</code>, and it is now a top-level node type instead of a subtype of marker. * A new modifier called "Replace Material" has been added to the engine. When this is assigned to an instance, it indicates that the material should be replaced for the named node in the instanced world or for all geometry nodes if no name is given. A material object can then be set for the instance node itself in order to specify what material gets applied to the affected geometries in the instanced world. * A new modifier called "Move Connector" has been added to the engine. This modifier takes an incoming connection attached to an instance node and redirects it to a named node in the instanced world. * Occlusion spaces and occlusion portals have been enhanced so that they can cull objects that may not be completely obscured by the occluder, but for which the unoccluded parts are outside the view frustum. * If both stencil shadows and shadow maps are enabled for a geometry node, and the geometry is rendered into the shadow map for a particular light source, then the geometry will no longer cast a stencil shadow for the same light source. * There is a new flag for sound sources that indicates that a sound should start playing from a random position each time it becomes audible. This works with looping, non-streamed sources, and it's useful in places where the same sound can be heard from multiple objects that are close together. * A new setting has been added to remote portals that allows you to specify a focal length multiplier for the camera used to render the scene through the portal. Values higher than 1.0 have a magnifying effect. * Impostors are now rendered with corners clipped off where possible to reduce dead fill. This results in a significant speed increase in scenes that make heavy use of impostors. An impostor's texture maps must be regenerated in order to calculate the clipping data. Corner clipping can be disabled for the top and/or bottom edges of an impostor in the impostor property settings used to generate the texture maps. * Node connectors now have keys that are strings up to 15 bytes in length, and the keys can contain any characters except <code>'$'</code>, <code>'%'</code>, and <code>'&'</code>, which are reserved for use by the engine. Nodes can advertise built-in connectors, and keys for those always begin with a <code>'%'</code> character. Connectors no longer carry information about what type of node they are allowed to connect to. * Inter-zone sound flow analysis has been improved significantly in this version. * A new function called <code>QueryProximity()</code> has been added to the <code>World</code> class. This function enumerates all geometry nodes and rigid bodies that intersect a given sphere and calls a user-supplied callback function. The <code>QueryProximity()</code> function replaces all previously existing node enumeration functions. * The <code>World::QueryWorld()</code> function has been renamed to <code>QueryCollision()</code>. === Effects === * Particle systems can now specify the <code>kParticleSystemSoftDepth</code> flag to enable soft geometry intersections. * Quad effects can now have soft geometry intersections enabled in their node settings. === Physics === * It is now possible to specify that the convex hull of a geometry be used for collision detection instead of the exact triangle mesh. This can be set under the Collision tab in the Node Info window. Using the convex hull produces much more stable collision detection for objects with small details, and it is much faster for all mesh geometries. === Interface Manager === * A new <code>PaintWidget</code> class has been added. It allows interactive painting on a canvas inside a rectangular viewport, and it exports functions for changing brush size, color, and fuzziness from scripts. * The <code>ImageWidget</code> class now lets you specify a secondary texture image, and it modulates the primary image. All subclasses of <code>ImageWidget</code> can also use this functionality, and it is particularly useful for masking camera widgets and movie widgets so they can have any shape you want. * The last visited directory for each type of resource opened with the file picker is now persistent and remembered in subsequent runs of the engine. This information is stored in the user's <code>engine.cfg</code> file as a series of <code>visit</code> commands. * File pickers now allow multiple files to be selected. This is enabled by setting the <code>kFilePickerMultipleSelection</code> flag when the file picker is constructed. The new <code>FilePicker::GetFileNameCount()</code> function can be used to determine how many files are selected, and the existing <code>FilePicker::GetFileName()</code> function now takes a file index as a parameter. === Scripting === * The execution model for scripts has been improved in this version. It is faster and more robust in cases where complex looping and branching structures are used. === System Utilities === * The data serialization system has been largely redesigned, and it no longer needs to call the <code>Pack()</code> function to determine the size of the data that will be serialized, but only to perform the actual serialization. Also, new functions called <code>BeginSection()</code>, <code>EndSection()</code>, <code>BeginChunk()</code>, and <code>EndChunk()</code> have been added to the <code>Packer</code> class to assist in the measurement of data sizes that are written to the output stream. * The <code>Packable::UnpackChunkList()</code> function template no longer takes a pointer to a callback function as its last parameter. Instead, this function always calls the <code>UnpackChunk()</code> function belonging to the class corresponding to the template parameter. * The term "cookie" is now used throughout the engine in reference to a user-defined pointer that is passed to callback functions. === Math Library === * A new <code>Antivector4D</code> class has been added to the engine, and it is now used to represent all planes. == Tools == === World Editor === * A bounding box is now displayed in the perspective viewport around the selected node that currently has the gizmo. (Tab and Shift-Tab can be used to move the gizmo to different selected nodes.) Clicking in a face of the bounding box with the Move tool lets you drag the node along the direction perpendicular to that face. Clicking on an edge of the bounding box with the Rotate tool lets you rotate the node about the axis parallel to that edge through the center of the box. * A new orbit camera tool has been implemented, and it works in the perspective viewport. The orbit camera tool orbits the camera about the center of the selected node that currently has the gizmo. If the Control key is pressed when you left-click in the viewport, then the orbit tool takes effect until you release the mouse button no matter what other tool might be currently selected. If there is no selection, then the center of the orbit is the world-space origin. * A new Paint page has been added to the editor, and it provides tools for painting into the texture maps held by paint spaces. The Paint page contains tools for setting brush color, strength, radius, and fuzziness as well as a channel mask and a popup menu with paint-related commands. The paintbrush tool lets you draw directly onto geometries in the perspective viewport, and this has the effect of altering the texture image belonging to the paint space associated with those geometries. The visual appearance of the paint texture depends on how it is used in the material shaders assigned to the geometries. * A world preview is now displayed when browsing world resources to be specified for a node setting. This is particularly convenient in the settings for the instance node so that you can see each prefab as you're browsing through your <code>Data</code> directory. The preview window adds an infinite light source to the world and sets the ambient light to 50%. You can move the camera by clicking and dragging inside the preview. * A sound preview is now available when browsing sound (<code>.wav</code>) resources to be specified for a node or object setting. Play and stop buttons appear whenever a sound file is selected. * Multiple worlds can now be simultaneously selected in the Worlds page. If more than one world is selected, then one of them is chosen at random each time you click in the scene to place an instance. * A new command called Paste Subnodes has been added to the Edit menu. This command is enabled when exactly one node is selected, and it pastes everything as subnodes of the selected node. * Changes made in the Node Info window can now be undone. This includes settings under all tabs as well as changes made in the Script Editor or Panel Editor. * The settings under the Collision tab in the Node Info window have been reversed so that you specify what kinds of collisions are allowed instead of what kinds of collisions are excluded. * When a material is imported from a <code>.mtl</code> file, it's name is now automatically set to the file name of the imported material resource, without the extension. * The Connectors pane in the Node Info window has been changed to display a list of built-in connectors available for a node in addition to the list of custom connectors that can be added by the user. * A title, such as "Top", "Left", "Perspective", or "Scene Graph", is now displayed in each viewport. These can currently be toggled off using the same button in the Grid page that toggles off the axes display. === Script Editor === * Output ports have been added to the method boxes in the Script Editor, and new fibers are now created by clicking in an output port and dragging to another method box. The separate fiber tool that previously existed has been removed. * After a new method is placed in a script, the current tool automatically switches back to the select/move tool. === Shader Editor === * Output ports have been added to the process boxes in the Shader Editor, and new routes are now created by clicking in an output port and dragging to another process box. The separate route tool that previously existed has been removed. * After a new process is placed in a shader, the current tool automatically switches back to the select/move tool. === Texture Tool === * There is now a dialog for generating terrain texture palettes. It can be opened by selecting "Generate Terrain Palette..." from the [[C4 Menu]] or by typing <code>texpal</code> with no parameters in the [[Command Console]]. * The time-consuming operations in the texture importer now get distributed to all available processors, and many textures can be imported ''n'' times faster with ''n'' cores. This applies to horizon map generation, ambient occlusion channel generation, alpha test bleeding, and S3TC compression. === Collada Importer === * The Collada import dialog now has a box where a scale factor can be entered. a23df77ed7720ea0041d16df29e4de17bedd402f Release Notes for Version 2.9 0 74 76 2023-07-15T10:10:19Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' May 20, 2012 * The C4 Engine now runs under Linux. Generic makefiles can be found in the <code>Linux</code> folder, and NetBeans projects can be found in the <code>NetBeans</code> folder. The engine builds for 64-bit by default. The Browser, Movies, and Font Generator plugins have not been brought to Linux yet. All other tool plugins and game modules are fully supported. == Core Engine == * The direct use of built-in integer types <code>l..." wikitext text/x-wiki __NOTOC__ '''Release date:''' May 20, 2012 * The C4 Engine now runs under Linux. Generic makefiles can be found in the <code>Linux</code> folder, and NetBeans projects can be found in the <code>NetBeans</code> folder. The engine builds for 64-bit by default. The Browser, Movies, and Font Generator plugins have not been brought to Linux yet. All other tool plugins and game modules are fully supported. == Core Engine == * The direct use of built-in integer types <code>long</code>, <code>unsigned long</code>, <code>short</code>,<code>unsigned short</code>, <code>signed char</code>, and <code>unsigned char</code> has been eliminated from the engine. The engine now defines the types <code>int8</code>, <code>unsigned_int8</code>, <code>int16</code>, <code>unsigned_int16</code>, <code>int32</code>, <code>unsigned_int32</code>, <code>int64</code>, and <code>unsigned_int64</code>, and these types are used throughout the source code. This was done to minimize potential differences across platforms and between 32-bit and 64-bit builds. (Note that the <code>char</code> type, which is a separate built-in type from <code>signed char</code> and <code>unsigned char</code>, is still used for character strings.) * The <code>GraphNode</code> class has been renamed to <code>GraphElement</code>. This is more consistent with the use of the term "element" in other containers (list element, map element, hash table element), and it avoids an ambiguity with the term "node" used to represent items in the scene. === World Manager === * When a rigid body is extracted from an instanced world, any connectors ending at the instance node are now transferred to the node to which the rigid body controller is assigned. === Interface Manager === * A new table widget has been added to the standard set of widgets built into the engine. A table is basically a list with a specified number of columns and a fixed cell size. === Message Manager === * A new message flag called <code>kMessageDestroyer</code> has been added. It should be set for controller messages that cause the target node to be destroyed and get sent with the <code>MessageMgr::SendMessageJournal()</code> function. This flag prevents the message from being deleted from the journal when the controller is destroyed on the server. == Tools == === World Editor === * There is a new Find page that contains functionality for finding nodes in a world. Nodes can be matched against a name field (which is not case sensitive), a node type, and a controller type. The name field can be left blank and the node and controller types can be set to <code>&lt;any&gt;</code> in order to match any node that satisfies the restrictions that are specified. The buttons at the bottom of the page let you find all matches, the next match, or the previous match. b94c5ffa513baa1558e7c895a9b0e7d6ed5944b4 Release Notes for Version 2.9.1 0 75 77 2023-07-15T10:10:50Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' June 1, 2012 * This release contains several performance improvements and minor bug fixes in addition to those mentioned below. == Core Engine == === Graphics Manager === * Each material attribute now has a flag called <code>kAttributeMutable</code> that determines whether the constant data, such as the color, stored in the attribute can be changed after a shader has been built. This flag is not set by default as an optimization that lea..." wikitext text/x-wiki __NOTOC__ '''Release date:''' June 1, 2012 * This release contains several performance improvements and minor bug fixes in addition to those mentioned below. == Core Engine == === Graphics Manager === * Each material attribute now has a flag called <code>kAttributeMutable</code> that determines whether the constant data, such as the color, stored in the attribute can be changed after a shader has been built. This flag is not set by default as an optimization that leads to higher shader performance. == Tools == === Collada Importer === * When animations are imported, there is now an option to preserve the current transform for any nodes that are missing from the input file instead of setting the transforms for those nodes to the identity. c9621e599ec3646a146942d1d1de3e53290d6ffa Release Notes for Version 2.10 0 76 78 2023-07-15T10:11:21Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' November 16, 2012 == Core Engine == * The engine can now be compiled for 64-bit Windows. New project files for Visual Studio 2012 are included, and they have 64-bit configurations in addition to 32-bit. * Several parts of the Mac OS X code in the engine have been rewritten to use the Cocoa API. The engine no longer calls any deprecated API functions, and it can compile with the latest Mac SDK for 32-bit and 64-bit targets. * The <code>fl..." wikitext text/x-wiki __NOTOC__ '''Release date:''' November 16, 2012 == Core Engine == * The engine can now be compiled for 64-bit Windows. New project files for Visual Studio 2012 are included, and they have 64-bit configurations in addition to 32-bit. * Several parts of the Mac OS X code in the engine have been rewritten to use the Cocoa API. The engine no longer calls any deprecated API functions, and it can compile with the latest Mac SDK for 32-bit and 64-bit targets. * The <code>float4</code> type has been renamed to <code>vec_float</code>, and new types <code>vec_int8</code>, <code>vec_int16</code>, <code>vec_int32</code>, <code>vec_unsigned_int8</code>, <code>vec_unsigned_int16</code>, and <code>vec_unsigned_int32</code> have been added. This affects your code only if you are directly using the engine's SIMD functions. * The <code>align_address</code> macro has been renamed to <code>alignas</code> to be consistent with the new C++11 keyword. * The Extras plugin has been eliminated, and most of the functionality it contained has been moved to the core engine (star field particle system, flash controller, rotation controller, and shock wave effect). === Movie Manager === * The Movies plugin based on QuickTime has been removed from the engine and replaced by a new proprietary cross-platform movie format. Movie compression and playback functionality is now part of the core engine in a new Movie Manager component, and it is available on all platforms supported by the engine. * Movie data is stored in a resource file with the extension <code>.mvi</code>. Movies can contain both video and audio tracks. * Video tracks are compressed using standard DCT and block truncation methods followed by a bit encoding that is optimized for fast decompression. This is a lossy compression technique with a variable quality level that can be controlled at the time a movie is generated. Pixel data is decompressed into the YCbCr 4:2:0 format, which is transformed into filtered RGB 4:4:4 format on the GPU using shader code. * The video codec supports key frames and delta frames for temporal compression. The frequency of key frames can be controlled at the time a movie is generated. * Audio tracks are compressed using a lossless technique to preserve perfect fidelity. * The Movie Manager uses an integer time base for which there are exactly 36000 ticks per second. This number was chosen because it is evenly divisible by the following numbers (plus others): 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 30, 32, 36, 40, 45, 48, 50, 60, 72, 75, 80, 90, 96, 100, 120. * Movies can be recorded inside the engine by using the <code>record</code> console command. This causes the engine to generate one or more "sequence" files containing raw video data and a single wave file containing raw audio data. These can be imported through the Movie Tool to create a compressed movie resource. === Interface Manager === * There is a new movie widget that is used to display movies in a panel or window. Movie widgets can be controlled from a script using the Play Movie, Stop Movie, Get Movie Time, and Set Movie Time controller functions. * A movie widget belonging to a panel effect can specify that its audio track be played through a connected source node. This allows the audio for a movie to be fully spatialized in a scene just like any other sound. * Paint widgets now have settings that can be used to specify the initial properties of the paint brush: radius, fuzziness, opacity, and color. === Graphics Manager === * The Combine Normals shader process has been extended so it can take an optional interpolation parameter. If the port named "t" has an input, then the normal "N1" is weighted by 1&nbsp;&minus;&nbsp;''t'' and the normal "N2" is weighted by ''t''. === Physics Manager === * The "mover" controller has been redesigned and replaced by the "movement" controller. The movement controller moves a node between a start and finish location at a constant speed with optional acceleration and deceleration at the beginning and end. The node to which a movement controller is assigned must have connectors that link to other nodes (usually markers) specifying the start and finish positions, and the connector keys used for this are specified in the controller settings. * The "rotation" controller previously in the Extras plugin has also been redesigned and moved into the core engine. The functionality has been split into two separate types of controllers: a "rotation" controller that is used for nodes that rotate in between two specific angles, and a "spin" controller that is used for nodes that rotate continuously about a given axis. The node to which either of these controllers is assigned must have a connector that links to another node (usually a marker) specifying the center and axis of rotation, and the connector key used for this is specified in the controller settings. Rotation takes place in the counterclockwise direction about the object-space ''z'' axis of the center node (which is shown in blue inside the World Editor). This means that reversing the direction of the ''z'' axis (by rotating the node 180 degrees about the ''x'' or ''y'' axes) causes the rotation to reverse direction. === World Manager === * The perspective exclusion mask for geometries, portals, and fog spaces has been modified so that visibility in the primary, reflection, and refraction perspectives can be controlled separately for direct rendering, rendering through a remote portal (that is not rendered into the reflection or refraction buffer), and rendering through a camera widget. * The perspective exclusion mask settings for the portal object and fog space object have been moved to the portal node and fog space node. * A perspective exclusion mask can now be set for all effect nodes, which include particle systems. === Scripting === * The previously existing method called Fade Ambient Source has been renamed to Vary Source Volume, and it can now be used on any type of source node to smoothly vary the playback volume. * A new script method called Vary Source Frequency has been added, and it can be used to smoothly increase or decrease the relative playback frequency of a source node. * If an instance node is the target of a Call Controller Function script method and the instanced world contains a rigid body, then the Script Editor now displays the available functions for the rigid body instead of the instance node. This makes sense because the rigid body inside an instanced world is always extracted and placed in the referencing world, and the instance node is deleted. === File Manager === * The <code>FileMgr::BuildFileList()</code> function has been replaced by the <code>FileMgr::BuildFileMap()</code> function. File names are now sorted on all platforms such that letter case is ignored and numerical parts of the names are sorted numerically instead of lexicographically. === Resource Manager === * The Resource Manager is now 100% thread-safe. Any type of resource can be loaded outside the main thread without risk of corrupting internal data structures. == Tools == === Movie Tool === * There is a new Movie Tool plugin that contains a movie player window and the movie generation functionality. The movie player can be opened by selecting Open Movie from the [[C4 Menu]], and a movie can be generated by selection Import Movie from the C4 Menu. * The movie generator can import a sequence of individual frames from TGA files and/or a group of sequence files that were recorded by the engine. (Each sequence file contains multiple frames.) Audio data for a movie is specified by a separate wave file. === World Editor === * A check box has been added to the [[Worlds Page]] that let's you click through instances already in the main world when placing a new instance node. * A modifier preset list has been added to the [[Worlds Page]]. A modifier preset stores a list of modifiers that can be assigned to instance nodes, and whenever a preset is selected, the modifiers stored in it are automatically assigned to each new instance that is placed in the scene. A modifier preset is created by selecting an instance node in the scene that already has modifiers assigned to it and selecting New Modifier Preset from the popup menu in the Worlds Page. Another menu command, Replace Modifiers, can also replace the modifiers for all currently selected instance nodes with the modifiers stored in the currently selected modifier preset. * A random Z offset range has been added to the [[Placement Page]]. This causes a node to be offset by a random distance in the specified range along the node's local ''z'' axis after the other placement adjustments have been made. This is useful for sinking objects into the ground by random amounts. === Script Editor === * The OK and Cancel buttons have been removed from the [[Script Editor]]. There are now items named Close and Save Script under the Script menu. * Boxes that display the letters "T" or "F" are now displayed on conditional fibers in a script that execute only if the result of the starting method is true or false. The fibers also still retain the green and red colors. === Shader Editor === * The OK and Cancel buttons have been removed from the [[Shader Editor]]. There are now items named Close and Save Shader under the Shader menu. bb80c4ee60104e7d2c1aff24c071522824b0e8ec Release Notes for Version 2.10.1 0 77 79 2023-07-15T10:12:00Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' December 1, 2012 * This release contains a few minor bug fixes for version 2.10. There are no new features. * Texture coordinates for cloth geometries are now generated by default so that the front and back sides of the cloth match. * Some problems that could occur when a shader is saved in the Shader Editor have been corrected. * Cases in which the text box in a save file picker would not be populated properly when a file name was click..." wikitext text/x-wiki __NOTOC__ '''Release date:''' December 1, 2012 * This release contains a few minor bug fixes for version 2.10. There are no new features. * Texture coordinates for cloth geometries are now generated by default so that the front and back sides of the cloth match. * Some problems that could occur when a shader is saved in the Shader Editor have been corrected. * Cases in which the text box in a save file picker would not be populated properly when a file name was clicked have been corrected. 24ef2ffc9ad55f00a9892cfd8bb64a5f78ff5bcd Release Notes for Version 2.10.2 0 78 80 2023-07-15T10:12:39Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' March 7, 2013 * This release several few minor improvements and bug fixes for version 2.10. There are no new features. * A problem with the shader used to render movies with an alpha channel has been corrected. * The collision detection structures have been expanded to handle meshes with a much larger number of triangles, and picking issues for dense meshes have been corrected. * Path control point picking in the World Editor has been im..." wikitext text/x-wiki __NOTOC__ '''Release date:''' March 7, 2013 * This release several few minor improvements and bug fixes for version 2.10. There are no new features. * A problem with the shader used to render movies with an alpha channel has been corrected. * The collision detection structures have been expanded to handle meshes with a much larger number of triangles, and picking issues for dense meshes have been corrected. * Path control point picking in the World Editor has been improved so that there are no problems at high zoom levels. * A potential problem restoring saved games containing water wave generators has been corrected. * Terrain geometries containing no triangles are now deleted when a world is loaded (and remain deleted when the world is then saved). 25a156ae74932ce9f1f2d23342d43130f8e426d3 Release Notes for Version 2.10.3 0 79 81 2023-07-15T10:13:06Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' March 31, 2013 * This release several few minor improvements and bug fixes for version 2.10. There are no new features. * A problem that could occur if a resource was requested twice with name strings having different case has been corrected. * The <code>EditTextWidget</code> now automatically sets the text rendering line count when multi-line editing is enabled. * The perspective exclusion mask is now correctly passed through from a pan..." wikitext text/x-wiki __NOTOC__ '''Release date:''' March 31, 2013 * This release several few minor improvements and bug fixes for version 2.10. There are no new features. * A problem that could occur if a resource was requested twice with name strings having different case has been corrected. * The <code>EditTextWidget</code> now automatically sets the text rendering line count when multi-line editing is enabled. * The perspective exclusion mask is now correctly passed through from a panel effect to any camera widgets it contains. * A possible problem with shaders using both alpha test and alpha-to-coverage has been corrected. * A deprecated keyboard function in the X Windows API has been updated under Linux. 0901c13bac8c5b1f04a5306c65077557ab1de07e Release Notes for Version 3.0 0 80 82 2023-07-15T10:14:27Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' July 29, 2013 '''WARNING:''' In version 3.0, all shaders are permanently changed to a new layout when a world is opened. See Shader Editor below. Just in case something goes wrong, please be sure to make a backup of your <code>Data</code> folder before running version 3.0. == Core Engine == * The Visual Studio projects now use shared property sheets to specify build settings. * The <code>ToolCode</code> directory has been removed, and al..." wikitext text/x-wiki __NOTOC__ '''Release date:''' July 29, 2013 '''WARNING:''' In version 3.0, all shaders are permanently changed to a new layout when a world is opened. See Shader Editor below. Just in case something goes wrong, please be sure to make a backup of your <code>Data</code> folder before running version 3.0. == Core Engine == * The Visual Studio projects now use shared property sheets to specify build settings. * The <code>ToolCode</code> directory has been removed, and all source files that were in that directory have been moved to the <code>PluginCode</code> directory. * The <code>VisualStudio2012</code> directory now contains a file named <code>C4.natvis</code> that provides some simple C4 data structure visualizers for use with the Visual Studio debugger. To use it, copy the file to your <code>Documents\Visual Studio 2012\Visualizers</code> directory. === Graphics Manager === * A large number of internal changes have been made to the low-level rendering system. On desktop platforms, the engine now runs with a core OpenGL profile, and OpenGL 3.2 or higher is required. * The engine can now render screen-space ambient occlusion (SSAO) as a post-processing effect. === Interface Manager === * The Rate window has been renamed to the Time window, and the associated <code>rate</code> command has been changed to the <code>time</code> command. The new Time window contains a lot more information about the time spent rendering each frame, and it displays enhanced timing graphs. * Push button widgets have a new setting that allows you to assign the Enter key or Escape key to a button, and the widget will automatically be activated when the assigned key is pressed. * Mouse wheel events now store the wheel delta in a new field of the <code>MouseEventData</code> structure instead of using the mouse position field. The current position of the mouse is now stored in the mouse position field as it is with all other mouse events. * In edit text widgets, the standard behavior of Shift-Home and Shift-End is now supported. * The edit text widget supports a new flag that causes the contents of the text box to be cleared when the user begins typing in it (or makes any edit). * The <code>IntegerSetting</code>, <code>PowerTwoSetting</code>, and <code>FloatSetting</code> constructors take two new optional parameters that specify special labels to be displayed in place of their actual values whenever the setting's current value is equal to the minimum or maximum allowable value. === Effect Manager === * Four new volumetric light shaft effects have been added to the core engine: box, cylinder, truncated pyramid, and truncated cone. They represent the extrusion of a rectangle and an ellipse with either parallel sides or tapered sides, and they are rendered by calculating the precise distance that light travels through the shaft at each point. The shaft effects have finite volume in the scene, but their interiors are rendered as if they were extruded to infinity along the shaft direction. See [[Light Shafts]] for more information. * Star field particle systems have a new setting that causes only stars that appear above the horizon to be rendered. Star fields are also rendered with higher performance compared to previous versions. * The [http://c4engine.com/docs/EffectMgr/Effect.html <code>Effect</code>] class has two new functions called <code>Wake()</code> and <code>Sleep()</code> that enable and disable calls to the <code>Move()</code> function. Effects are now asleep by default so that time isn't wasted calling <code>Move()</code> functions that don't do anything. To make sure that the <code>Move()</code> function is called for custom effects, call the <code>Wake()</code> function from inside the <code>Preprocess()</code> function. === World Manager === * Version 3.0 includes a new high-level visibility system that constitutes the largest architectural upgrade in the history of the C4 Engine. Each world now contains a number of DAGs (directed acyclic graphs) that are independent of the of the node-subnode relationships in the transform tree. There are separate DAGs for geometries, effects, triggers, fields, etc., and they include cell hierarchies that enable fast visibility, collision, and proximity searching. The most important aspect of the new visibility system is that each node can now exist in multiple zones simultaneously within the DAG that it belongs to. It's now the usual case that nodes should simply be placed in the infinite zone, and the engine automatically determines inside which subzones the node needs to be visible. When a node is completely covered by one or more subzones, then the engine knows that it does not need to be visible in the enclosing zone. Nodes can still be explicitly placed inside subzones to exert some control over where they are visible, and this also makes the visibility system backwards compatible with existing worlds from previous versions of the engine. * Each node has a new setting that lets you control the maximum subzone depth in which it is eligible for visibility, where the depth is measured in terms of the zone hierarchy in the transform tree. This can be useful for level optimization by providing some control over which zones large objects are visible in. By default, the maximum subzone depth is unlimited. * Nodes can also be forced to be visible in its owning zone and all subzones up to a maximum subzone depth. By setting the forced subzone depth to zero, a node is forced to be visible in its owning zone in the transform tree, and it can still be visible in subzones if the maximum subzone depth is greater than zero. This setting is useful, as an example, for making sure that nodes composing the outer walls of a building are visible both inside and outside without requiring that the node actually extend outside the inside zone's boundary. This setting is also useful for forcing light sources (especially infinite lights) to be rooted in multiple zones without having to use large portals that serve no other purpose. * The <code>Node::EnterZone()</code> and <code>Node::ExitZone()</code> functions have been removed from the engine. The notion that a node belongs to one zone at a time no longer applies under the new visibility system, and nodes no longer get reparented to the zones that contain them as they move around a level. * The <code>World::FindZone()</code> function has been removed from the engine. It is no longer necessary to determine what zone contains a particular location in order to place new nodes in the world. New nodes should ordinarily be added to the root infinite zone of the world now, and the engine will automatically insert them into the zone-based visibility structures. * There is a new <code>World::AddNewNode()</code> function that can be used to add a node to the root infinite zone of the world and preprocess it. * A new node flag has been added that allows subnodes to be animated as part of a model even if the node itself does not have animation applied to it. * An array of default property types can now be specified in model registrations. When a new model is placed in the World Editor, properties of these types are automatically attached to the model node. See the [http://c4engine.com/c4engine/doco/WorldMgr/ModelRegistration.html <code>ModelRegistration</code>] class. * Paint spaces have a new setting that enables mipmap generation for their paint textures. * A perspective mask can now be set for light nodes so that they can be disabled in reflections, refractions, etc. * There are two new modifiers that enable and disable interactivity in an instanced world. * A node type setting has been added to the Delete Nodes modifier. This allows all nodes of a specific type, or nodes of a specific type with a specific name, to be deleted from an instanced world. The addition of this setting makes the Remove Lights and Remove Sources modifiers redundant, so those modifiers have been removed from the engine. Any existing uses of those modifiers will automatically be converted to Delete Nodes modifiers with the corresponding node type. * A new modifier called Set Perspective Mask has been added, and it can specify the perspective mask for a specific type of node and/or nodes with a specific name in an instanced world. * The structure buffer is now rendered for images generated by camera widgets in panel effects. This allows shaders dependent on the scene depth to render correctly, and it enables post-processing effects like SSAO in camera widgets. * The dome zone type has been removed from the engine. Any existing dome zones will be converted to the smallest enclosing cylinder zone instead. * A new geometry flag has been added that allows a geometry node inside an instanced world to use a paint space inside the instancing world. A built-in <code>%Paint</code> connector has been added to instance nodes to facilitate this feature. If the "Use paint space in instancing world" box is checked for a geometry and the geometry is not directly connected to a paint space, then it associates itself with the paint space connected through the <code>%Paint</code> connector of an instance node preceding it in the node hierarchy. * In the context of the model animation system, the term "Track" has been replaced by the term "Sequence". This was done to distinguish the terminology from the the "Track" used by movies and audio resources. * A direct portal that is not connected to any target zone is now automatically connected to the zone enclosing the zone in which the portal has been placed. * Direct portals have a new flag that prevents sound from flowing through them. === Controller System === * A new virtual function named <code>InstanceExtractable()</code> has been added to the <code>Controller</code>. A subclass should override this function and return <code>true</code> if the particular type of controller contains state that needs to be preserved across a saved and restored game. If such a controller appears in an instanced world, then this causes the nodes to be extracted so that they are saved and restored with the world instead of reloaded from the original instanced world. In the core engine, the <code>RigidBodyController</code>, <code>MovementController</code>, and <code>RotationController</code> classes override the <code>InstanceExtractable()</code> function and return <code>true</code>. Everything else returns <code>false</code>. === Physics Manager === * A new function called <code>PurgeContacts</code> has been added to the <code>RigidBodyController</code> class. It simply purges all outgoing and incoming edges in the contact graph. * A new function called <code>PurgeGeometryContacts</code> has been added to the <code>PhysicsController</code> class. It purges all existing contacts between a particular geometry node and all rigid bodies in the world. * The <code>kRigidBodyDetached</code> enumerant has been renamed to <code>kRigidBodyContactsBroken</code>, and a new enumerant named <code>kRigidBodyGeometryContactsBroken</code> has been added. See the [http://c4engine.com/c4engine/doco/PhysicsMgr/RigidBodyController_HandleNewRigidBodyContact.html <code>RigidBodyController::HandleNewRigidBodyContact</code>] and [http://c4engine.com/c4engine/doco/PhysicsMgr/RigidBodyController_HandleNewGeometryContact.html <code>RigidBodyController::HandleNewGeometryContact</code>] functions. * A new space type called a Physics Space has been added, and it can be used to define a global bounding box for the physics simulation. A new member function of the <code>RigidBodyController</code> class named <code>HandlePhysicsSpaceExit()</code> is called whenever a rigid body goes outside the physics space. This is useful for detecting when an object flies off a level for some reason so that something can be done about it (usually just deleting the object). A physics space is enabled by connecting the physics node to the physics space using the built-in <code>%Physics</code> connector. * A new controller flag named <code>kControllerPhysicsSimulation</code> has been added, and it should be set by any controller that acts as the main interface between the engine and a physics library. This identifies the controller to the World Manager as the sole physics controller in a world and causes it to get special treatment. * A new controller called the Oscillation Controller has been added to the core engine. It works like the movement controller, but it continuously oscillates the position of its target node between a start and finish location. == Tools == === World Editor === * The World Editor contains a new Landscaping page. This is a work in progress and is not fully functional at this time. * Star fields are now rendered in the World Editor. * When using the mouse wheel to zoom in orthographic viewports or the scene graph viewport, the zoom is now centered on the cursor position. This change has also been made in the Shader Editor, Script Editor, and Panel Editor. * Double-clicking on a connector now selects the node it is connected to, if any. * A new button labelled "Create Opposing" has been added to the Portals page. For each selected direct portal, call the zone in which the portal resides Zone A and the zone to which the portal is connected Zone B. The Create Opposing button creates a new direct portal in Zone B that is connected to Zone A. The new portal is coincident with the original portal and has the same set of vertices, but faces the opposite direction. === Shader Editor === * The separate tabs for ambient and light shaders have been eliminated, and there is now a single shader graph containing output nodes for both the ambient and lighting passes. Separate passes for existing shaders are automatically merged, and any redundancies due to common calculations in both passes are automatically unified. * Four new interpolant processes called Full Tangent-Space Light Vector, Full Tangent-Space View Vector, Full Object-Space Light Vector, and Full Object-Space View Vector have been added to the Shader Editor. These provide access to the unnormalized vectors corresponding to the differences between the interpolated vertex position and either the light position or camera position. The Magnitude&nbsp;3D process can be applied to these in order to determine the exact distance between the point being shaded and the light position or camera position. * Four new mathematical processes that perform comparisons have been added to the Shader Editor. A result of 0.0 or 1.0 can now be generated based on the comparisons equal, not equal, less than, greater than, less than or equal, and greater than or equal. * When a shader process is selected, all input and output routes are now highlighted. === Script Editor === * When a script method is selected, all input and output fibers are now highlighted. * Two new built-in script methods named "Set Color Value" and "Set Vector Value" have been added. These methods allow you to specify the values for the individual components of a color, vector, or point variable. === Texture Tool === * Textures can now be generated in a two-channel red-green format or a one-channel red format. When sampled in a shader, these formats are read as RG01 and R001, respectively, meaning that the alpha channel is always 1.0 and the missing color channels are always 0.0. * Cube maps can now be imported from the following four possible layouts. The appropriate layout is automatically selected based on the dimensions of the input image. # The previously supported native layout in a vertical strip having height exactly six times its width. # A horizontal strip having width exactly six times its height. # A horizontal cross layout having a width to height ratio of 4:3. # A vertical cross layout having a width to height ratio of 3:4. b16ef24a663203f3f552be8fc9ef95edfdf1e03b Release Notes for Version 3.5 0 81 83 2023-07-15T10:15:26Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' January 8, 2014 * This release includes a utility function that automatically updates all world and model resources so that they use the newest format. The engine currently contains a significant amount of code that's necessary to support old formats going back many years, and this code will be removed from version 4.0. It will be necessary to run the update utility in version 3.5 before your world and model resources can be used in version..." wikitext text/x-wiki __NOTOC__ '''Release date:''' January 8, 2014 * This release includes a utility function that automatically updates all world and model resources so that they use the newest format. The engine currently contains a significant amount of code that's necessary to support old formats going back many years, and this code will be removed from version 4.0. It will be necessary to run the update utility in version 3.5 before your world and model resources can be used in version 4.0. The utility is run by typing <code>updateworlds</code> in the command console. This utility searches the <code>Data</code> directory hierarchy for all <code>.wld</code> and <code>.mdl</code> resources, unpacks the data inside each one, and then saves them back out to the disk. '''Note that this will overwrite all existing <code>.wld</code> and <code>.mdl</code> files in the <code>Data</code> directory. Please make a backup of your entire <code>Data</code> directory before using this utility just in case something goes wrong.''' == Core Engine == * The engine now includes integrated support for the [[Open Data Description Language]] (OpenDDL). The general language parsing functionality is abstracted by the new [http://c4engine.com/docs/System/DataDescription.html <code>DataDescription</code>] class, and data structures described by OpenDDL files are represented by the new [http://c4engine.com/docs/System/Structure.html <code>Structure</code>] class hierarchy. Specific file formats based on OpenDDL are defined by creating a subclass of the <code>DataDescription</code> class to represent the format as a whole and by creating subclasses of the <code>Structure</code> class to represent each of the various data structures that can be used in the format. * The <code>MeshGeometry</code> class has been renamed to <code>GenericGeometry</code>, and the <code>GeometryLevel</code> class has been renamed to <code>Mesh</code>. This was done because <code>Mesh</code> objects don't necessarily have a one-to-one correspondence with levels of detail any more. * The console command history is now saved out when the engine config file is written (or when the engine exits, if necessary). It is restored the next time that the engine starts up, and commands previously entered into the console can be accessed with the up arrow key. * Under Windows, Visual C++ 2013 is now required to build C4, and under Linux, GCC 4.8.1 is now required to build C4. The engine uses newer features of the C++ language that are not supported by earlier versions of these compilers. (Visual C++ 2012 is still used for the PS4.) === Graphics Manager === * The engine contains a new ambient shading feature called ''radiosity spaces''. These are similar to the existing ambient spaces in that they store volumetric lighting information on a 3D grid. A radiosity space contains information about the directional reflected light intensity and color reaching each sample point inside the space. This provides an enormous boost in the realism of the ambient lighting in a level, and it affects dynamic objects passing through a radiosity space as well as static geometry. * The data for ambient spaces (and radiosity spaces) is now stored inside the world instead of in separate texture resources. After a world resource has been updated to version 3.5, the previously existing ambient texture resources should be deleted. * The built-in shading code for rendering halfspace fog on objects infinitely far away has been refined and now produces more accurate results. This effects skyboxes and any effects rendered at infinity. * This release includes preliminary support for Oculus Rift on Windows, and Mac and Linux support will follow. This has to be enabled by defining <code>C4OCULUS</code> to be <code>1</code> at the top of <code>C4Oculus.h</code> and rebuilding the engine. (It's necessary to add the Oculus SDK include and library paths to the project settings as well.) To actually display stereo rendering, the system variable <code>$displayOculus</code> needs to be set to "1" in the <code>engine.cfg</code> file (in the user's roaming folder, see [[File Locations]]). When stereo rendering is active, the resolution of the display is always set to the native resolution of the Oculus Rift (1280&times;800 in the devkit). Vertical sync should be enabled to prevent tearing. ''This is preliminary support only.'' The overall performance and demo game functionality does not represent what the final version will be like. In particular, there is currently no sharing of computation between rendering for the left and right eyes, the visibility code has not been updated to account for two camera positions, and the game code simply adds head tracking on top of the mouse input. === World Manager === * Trigger nodes now generate different events for activation and deactivation. There are two separate connector key settings that can be used to send these events to different controllers, or they may be sent to the same controller. * A camera shaking effect has been added to the core engine, and it can be used to rattle the camera for explosions, earthquakes, etc. The effect is implemented as part of a new <code>Adjuster</code> class hierarchy that may be expanded in the future. * The distance occlusion capabilities of fog spaces have been enhanced. Distance occlusion in the horizontal and vertical directions (relative to the fog plane) can now be enabled separately, and the fog intensity at which objects are culled can now be explicitly specified. * The <code>Modifier</code> class now has a virtual <code>operator ==</code> function that should be overridden by all custom modifier subclasses. It's used by the World Editor to determine whether two instances have the same modifiers with the same settings. * The concept of transition zones has been removed from the engine. They have been rendered obsolete by the new multi-zone system, and they were always kind of a messy hack. === Controllers === * Two new controllers for light nodes have been added to the core engine, the Strobe Controller and the Flicker Controller. The Strobe Controller causes a light to alternate between two colors at random times within specified intervals, and it is suitable for things like electric lights. The Flicker Controller causes a light to continuously flicker in intensity and move around slightly about its original position, which is suitable for things like fire. * A new Shader Parameter Controller has been added to the core engine, and it can be assigned to geometry or effect nodes. It observes a controller attached to another node and forwards the output of that controller to a shader parameter for the geometry or effect node to which it is assigned. As an example, this could be used to vary the emission intensity of some geometry's material in sync with the strobing of a light source. The Shader Parameter Controller modifies a shader parameter only for its target node and not for all nodes using the same material. === Physics === * The cloth simulation has been more tightly integrated with the physics system, and a new rope simulation has been added to the engine. The rope controller is similar to the cloth controller, and it simulates a one-dimensional string of masses connected by spring-dampers to produce realistic ropes, cables, etc. Both the cloth controller and rope controller are subclasses of a new "deformable" controller that encapsulates common functionality. The mass-spring-damper simulation stages for multiple cloth and rope controllers can now run in parallel on multiple processors (whereas previously, only the geometry updates ran in parallel). * New settings have been added to the cloth controller to provide more control over the simulation, and these include damper settings and internal resistance for greater stability. The same settings are also available for the rope controller. * A rope geometry can be "attached" at either end (or both ends), and each attachment can be a fixed point in space, another node (which can be moving), or a direct subnode of a rigid body. If a rope is attached to a rigid body, then the rope simulation exerts a force on the rigid body through the tension in the rope. * Attachment settings for the cloth geometry have been moved to the cloth controller. * A rope attachment can be broken when a world is running by using the Break Attachment script function for the rope controller. * Both the cloth and rope controllers can now be warmed up when a world is loaded so that they have a chance to reach a steady state before being rendered. * The time before cloth and rope controllers automatically go to sleep when they haven't been rendered can now be specified by the user. When a cloth or rope controller goes to sleep automatically, it wakes back up the next time it is rendered. If a cloth or rope geometry is connected to an exclusive force field through its <code>%Wind</code> connector, then any controller assigned to that force field is put to sleep and awoken at the same time as the cloth or rope controller. If either end of a rope is attached to a rigid body, then the rope will not automatically go to sleep unless the rigid body has gone to sleep. If the rigid body is awakened by the physics simulation, then it also awakens any ropes attached to it. * There is a new set of nodes called "blockers" that can be used to block the motion of a cloth or rope geometry. A cloth or rope geometry can be connected to a blocker node through the built-in <code>%Blocker</code> connector. * Cloth and rope simulations are now affected by all force fields that they intersect. === Interface Manager === * Begin and end hover events are now generated for widgets when the mouse cursor is placed over them. * Anchor modes can now be set for the horizontal and vertical position of a widget. These let you specify that a widget should maintain its position relative to the boundaries of a window when the window is resized. === Particle Systems === * Emitter nodes can now have a precalculated height field associated with them. The values in the height field represent the actual height of world geometry relative to the bottom surface of the emitter. This information makes it possible to emit particles over the actual surface of the ground, for instance, instead of only at one end of an emitter. === Scripting === * Script controllers and widgets can now have multiple scripts attached to them, and each script can be run in response to a specific set of events. Scripts can also determine what type of event caused them to execute and take conditional execution paths based on the result. == Tools == === World Editor === * The World Editor now includes an import plugin that can read the [[Open Game Engine Exchange]] (OpenGEX) format. This is available, in addition to the Collada format, when Import Scene is selected from the World menu. The World Editor remembers which format was last imported and selects the same format by default the next time a scene is imported. * The volumetric lighting information stored in ambient spaces and radiosity spaces is now generated by using the popup menu in the [[Lights Page]]. * There is a new command under the Edit menu called Select All In Zone. This is available when one or more zones are already selected, and it adds all nodes belonging to each zone's cell graphs to the selection as well as all subnodes of each zone. This effectively selects everything that is considered by the engine when the selected zones are processed for rendering, trigger activation, and force field application. * There is a new command under the Node menu called Select Incoming Connecting Nodes. This selects all nodes in the scene having connectors that are connected to the current selection. * The Geometries page now includes a new rope geometry next to the existing cloth geometry. A rope geometry always has a rope controller assigned to it that can be configured under the Controller tab in the Node Info window. * The Physics page contains new tools for drawing blocker nodes (plate, box, cylinder, sphere, and capsule). Blocker nodes are used only by cloth and rope controllers. * If a node is hidden in an instanced world, it will now also be hidden in the instancing world when loaded in the World Editor. * The popup menu in the Worlds Page contains two new items that expand and collapse all instances of the selected worlds in scene graph viewports. * There is a new popup menu in the Models Page that contains commands for selecting all or some models and for expanding/collapsing all models in scene graph viewports. * In the Worlds Page, double-clicking on a modifier preset now causes all of the instance nodes in the world having exactly the same set of modifiers with exactly the same settings to be selected. * In the Particles Page, double-clicking on a particle system now causes all particle systems in the world having the same type to be selected. * The Particles Page now has a popup menu that contains a couple new commands. One command selects all particle systems of the type of the one currently selected in the list of registered particle systems. A second commands generates height field data for the currently selected emitter nodes. An emitter must have the "Enable height field" box checked in order to have a height field generated. * The material pickup tool now cycles through multiple materials applied to a geometry node when the tool is used in the scene graph viewport. That is, if a geometry has more than one material, then clicking on the geometry in the scene graph viewport once will pick up the first material, clicking on the same geometry a second time will pick up the second material, etc. * The Spaces Page has been removed from the World Editor, and the tools for drawing the various types of spaces have been moved to other pages containing related tools. The shadow space and ambient space tools have been moved to the Lights Page, the acoustics space tool has been moved to the Sources Page, the occlusion space tool has been moved to the Portals Page, the paint space tool has been moved to the Paint Page, and the physics space tool has been moved to the Physics Page. * The Skyboxes Page has been renamed to the Atmosphere Page, and the fog space tool has been moved to this page. === OpenGEX Importer === * An importer plugin for the OpenGEX format is now included with the engine. OpenGEX export plugins (including source) for various modeling programs can be found on the official website at [http://opengex.org/ opengex.org]. === Shader Editor === * A new Fragment Depth process has been added to the Shader Editor. It outputs a scalar value representing the linear depth of the fragment being rendered in camera space. === Script Editor === * The Script Editor now supports editing multiple scripts for the same object. A list of scripts is displayed on the left side of the editor window, and new scripts can be added at any time. Each script has a name (that is only used by the editor) and a set of events that it can handle. Scripts belonging to a script controller attached to a node can handle controller activation and controller deactivation events. Scripts attached to a widget can handle widget activation, widget change, and widget begin/end hover events. It's possible for a script to handle no events at all, in which case it can only be run by checking the "Execute script when loaded" box for a script belonging to a script controller. * The Script Editor maintains a separate selection and undo stack for each script. You can switch among scripts by clicking on them in the scripts list or using Ctrl-1 through Ctrl-9 as shortcuts. Double-clicking on a script opens the dialog in which the name and event types can be specified. * There is a new Events tab in the Methods page. Event methods simply generate a boolean value indicating whether the specific type of event they represent is the type that caused the script to run. Event methods do not have any settings, and the Method Info window cannot be opened for them. When fibers are drawn from an event method to another method, the Script Editor automatically assigns a condition of True to the fiber so that all succeeding methods execute only if the event type matches. === String Importer === * The String Importer tool now expects input files to be in the OpenDDL format, but still using the <code>.txt</code> extension. The string table format defines a single data structure called <code>Entry</code> that can contain a <code>string</code> primitive and/or other <code>Entry</code> structures. Each <code>Entry</code> structure must specify an <code>id</code> property, which is a 32-bit unsigned integer that's usually written as a four-character code. * There is a conversion utility that will automatically create OpenDDL-formatted text files for all existing string table resources. The utility is run by typing <code>updatestrings</code> in the command console. This utility searches the <code>Data</code> directory hierarchy for all <code>.str</code> resources and uses the data in each one to create a corresponding <code>.txt</code> file in the <code>Import</code> directory hierarchy. '''Note that this will overwrite any existing <code>.txt</code> files in the <code>Import</code> directory that were previously used to create the string table resources. Please make a backup before using this utility just in case something goes wrong.''' d35ab17b3b233a00b45966d48c97d25f3f6a885b Release Notes for Version 3.5.1 0 82 84 2023-07-15T10:16:30Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' January 22, 2014 * The <code>updateworlds</code> utility included with version 3.5 has been expanded to update panel and material resources in addition to the world and model resources that it previously updated. This utility is run by typing <code>updateworlds</code> in the command console, and it should be run to prepare your resources for version 4.0. '''Note that this will overwrite all existing <code>.wld</code>, <code>.mdl</code>, <co..." wikitext text/x-wiki __NOTOC__ '''Release date:''' January 22, 2014 * The <code>updateworlds</code> utility included with version 3.5 has been expanded to update panel and material resources in addition to the world and model resources that it previously updated. This utility is run by typing <code>updateworlds</code> in the command console, and it should be run to prepare your resources for version 4.0. '''Note that this will overwrite all existing <code>.wld</code>, <code>.mdl</code>, <code>.pan</code>, and <code>.mtl</code> files in the <code>Data</code> directory. As always, please make a backup of your entire <code>Data</code> directory before using this utility just in case something goes wrong.''' == Tools == === OpenGEX Importer === * The OpenGEX Importer has been updated to support the latest version of the OpenGEX specification, available at [http://opengex.org/ http://opengex.org/]. === World Editor === * When a scene is saved as a model resource, if a lone group node exists at the root of the scene, then it will no longer be stripped out. e21b63f86f28908c68bafa71ab6362e6878b8d5b Release Notes for Version 4.0 0 83 85 2023-07-15T10:17:08Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' October 14, 2014 * Note that version 4.0 may not be able to read world, model, panel, and material resources that were saved in versions earlier than version 3.5. Older resources should be updated using the [[Release Notes for Version 3.5 | <code>updateworlds</code> utility in version 3.5.x]] before using them in version 4.0. * Like version 3.5.x, this release contains a utility that updates world and model resources to the current format...." wikitext text/x-wiki __NOTOC__ '''Release date:''' October 14, 2014 * Note that version 4.0 may not be able to read world, model, panel, and material resources that were saved in versions earlier than version 3.5. Older resources should be updated using the [[Release Notes for Version 3.5 | <code>updateworlds</code> utility in version 3.5.x]] before using them in version 4.0. * Like version 3.5.x, this release contains a utility that updates world and model resources to the current format. Even though not strictly required, this utility should be run to update worlds and models so that some parts do not need to be converted by the engine on the fly every time the resources are loaded. The utility is run by typing <code>updateworlds</code> in the command console. '''Note that this will overwrite all existing <code>.wld</code> and <code>.mdl</code> files in the <code>Data</code> directory. Please make a backup of your entire <code>Data</code> directory before using this utility just in case something goes wrong.''' * In this release, the two separate texture resources that were previously used for horizon maps have been consolidated into a single texture resource. Existing horizon maps must be updated before they can be used in version 4.0, and there is a utility function that automatically updates all horizon map texture resources to the new format. The utility is run by typing <code>updatetextures</code> in the command console. This utility searches the <code>Data</code> directory hierarchy for all <code>.tex</code> resources that contain horizon maps and combines the files whose names end in <code>-h1</code> and <code>-h2</code> into a single file. If the file names end in <code>-nrml-h1</code> and <code>-nrml-h2</code>, then the combined file name ends in <code>-hrzn</code>. Otherwise, the number is removed from the end of the file name so that the combined file name ends in <code>-h</code>. '''Note that this will delete all existing <code>.tex</code> files containing horizon maps in the <code>Data</code> directory and create new replacement files. Please make a backup of your entire <code>Data</code> directory before using this utility just in case something goes wrong.''' == Core Engine == * The Mac version of C4 now requires Mac OS 10.9 Mavericks as the minimum supported operating system. This ensures that OpenGL 3.3 is available on all supported hardware. * The engine includes a new header file called <code>C4Options.h</code> that contains several switches for controlling compilation options. These include defines for things like legacy resource support, memory leak detection, statistics counters, debug rendering, and resource logging. * In the <code>Tree</code> class, the functions <code>AddSubnode()</code>, <code>AddFirstSubnode()</code>, <code>AddSubnodeBefore()</code>, and <code>AddSubnodeAfter()</code> have been renamed to <code>AppendSubnode()</code>, <code>PrependSubnode()</code>, <code>InsertSubnodeBefore()</code>, and <code>InsertSubnodeAfter()</code>, respectively, for consistency with similar functions belonging to other types of container classes. * The global constants <code>K::identity_3D</code> and <code>K::identity_4D</code> have been replaced by the special structures <code>Identity3D</code> and <code>Identity4D</code>. This is to be consistent with the existing structures <code>Zero2D</code>, <code>Zero3D</code>, etc. === Graphics Manager === * On the PlayStation 4, the low-level rendering code has been largely rewritten. It now has minimal external dependencies, and it is much faster. * Stencil shadows have been removed from the engine, and all shadows are now rendered with shadow mapping. * The infinite light, depth light, and landscape light have been merged into a single type of light that uses the name infinite light. Existing lights are automatically converted to the new type where necessary. * The engine can now combine the shaders for ambient light and infinite lights into unified shaders that calculate both of these at once. In complex scenes, this generally provides a speed increase of about 10%&ndash;20% on fast GPUs, and it has the added benefit that only half as many individual shaders need to be compiled for large outdoor areas. In order to use the unified shaders, the new check box "Light can be unified with ambient" must be selected in the settings for an infinite light node. (This box is initially checked for newly created infinite lights.) * There is a new material flag called <code>kMaterialRadiositySpaceInhibit</code> that prevents radiosity spaces from contributing to the ambient lighting. * Radiosity spaces can now have non-power-of-two dimensions. Higher-quality data is also generated, and most importantly, normal mapping can now affect the radiosity lighting. To use normal-mapped radiosity, the tangent-space normal vector should be routed to the '''N''' input of the Ambient Lighting Output process. (This is done automatically for standard materials.) * The Texture Map and Environment Output shader processes now have an optional "bias" input port. The bias is a scalar quantity that gets added to the mipmap level computed by the hardware during trilinear filtering. Positive bias values cause higher-numbered mipmaps to be sampled, which are blurrier due to their lower resolution. Negative bias values cause lower-numbered mipmaps to be sampled, which sharpens the texture image, but be warned that using negative bias values can impact performance. * The Horizon Map shader process now has a single texture map setting. The eight channels of horizon data has been consolidated into a single texture map as an array of 2D images. * A new shader process called "Primitive Facing" has been added to the engine. It is useful when rendering geometry with two-sided materials, and it always produces the scalar value 1 for front faces and &minus;1 for back faces. * The <code>GraphicsMgr::DrawRenderList()</code> function has been renamed to the shorter <code>GraphicsMgr::Draw()</code>, and it can now take a list of <code>Renderable</code> objects or an <code>Array</code> of pointers to <code>Renderable</code> objects. * The material attribute classes that involve texture maps have been renamed for consistency and clarity. The <code>MapAttribute</code> base class is now named <code>[http://c4engine.com/docs/GraphicsMgr/TextureAttribute.html TextureAttribute]</code>, and the specific subclasses are named <code>[http://c4engine.com/docs/GraphicsMgr/DiffuseTextureAttribute.html DiffuseTextureAttribute]</code>, <code>[http://c4engine.com/docs/GraphicsMgr/SpecularTextureAttribute.html SpecularTextureAttribute]</code>, <code>[http://c4engine.com/docs/GraphicsMgr/EmissionTextureAttribute.html EmissionTextureAttribute]</code>, <code>[http://c4engine.com/docs/GraphicsMgr/NormalTextureAttribute.html NormalTextureAttribute]</code>, <code>[http://c4engine.com/docs/GraphicsMgr/HorizonTextureAttribute.html HorizonTextureAttribute]</code>, <code>[http://c4engine.com/docs/GraphicsMgr/OpacityTextureAttribute.html OpacityTextureAttribute]</code>, and <code>[http://c4engine.com/docs/GraphicsMgr/EnvironmentTextureAttribute.html EnvironmentTextureAttribute]</code>. One important change is that the term "gloss" is no longer used in conjunction with a specular color texture map. === Physics Manager === * The constraint solver in the physics system has been largely redesigned and is now considerably more accurate and a lot faster. * Contact graph islands are now solved in separate jobs to take greater advantage of multiple cores. * Rigid bodies have a new sleep box multiplier setting that controls how quickly an object will go to sleep if it's not moving very much. * The friction model has been updated to be more accurate. Friction coefficients should generally be about 25 times greater than before. When old worlds are opened or played, the friction coefficients for all rigid bodies will automatically be multiplied by 25 to match the new code. * Rolling resistance has been implemented in a new way that is a lot more effective. Rolling resistance values should generally be about 2% of their previous values. When old worlds are opened or played, the rolling resistance values for all rigid bodies will automatically be multiplied by 0.02 to match the new code. * Restitution has been updated and now behaves as expected for all rigid bodies. Bouncing objects come to a rest naturally. * A new spin friction feature has been added that applies to objects that are spinning on a single point on the ground like a top. Since there is no tangential motion, ordinary friction does not apply, so the spin friction was added to account for this case. * All joints have been re-implemented and are much more accurate than before. * The universal joint has a new setting that determines whether the twist orientation of the rigid bodies connected to it are locked. This twist constraint can look a little odd for swinging objects, so it's possible to turn it off for objects when the exact orientation doesn't matter. * Joints can now be broken when enough force is applied to them. When a joint is broken, its controller is activated, if it has one, so that a script can be run in response. (Joints can also be explicitly broken by a script as described below.) * Joints can now have distance and angular limits. Distance limits can be applied to the cylindrical and prismatic joints, and angular limits can be applied to the spherical, universal, discal, revolute, and cylindrical joints. * Each joint has a new constraint solver iteration multiplier setting that controls how long the physics system will spend calculating the constraint solution for the island containing the joint. This multiplier can be increased for joints that need extra stability. === Interface Manager === * A new widget type called <code>[http://c4engine.com/docs/InterfaceMgr/TreeWidget.html TreeWidget]</code>, a subclass of <code>[http://c4engine.com/docs/InterfaceMgr/ListWidget.html ListWidget]</code>, has been added, and it displays a list of items for which sub-items can be shown or hidden by the user as a hierarchical tree. * Some new functionality has been added to the mouse wheel so that it's possible to scroll a widget containing other scrollable widgets without spontaneously switching focus when another scrollable widget happens to move underneath the mouse pointer. Basically, the mouse wheel will stick to the widget on which it was originally used unless the mouse pointer is moved far enough to re-focus. * Some new security features have been added to the <code>[http://c4engine.com/docs/InterfaceMgr/PasswordWidget.html PasswordWidget]</code> class to prevent things like inadvertent leakage to the swap file. === World Manager === * The method by which the World Manager keeps track of nodes that need updating has been redesigned, and the new system provides a major performance increase for all worlds. The more nodes there are in a world, the larger the performance benefit. Some of the large worlds in our game ''The 31st'' have had their frame times drop to 40% of their previous values, meaning that they now run more than twice as fast as before. * Point lights now have settings for a minimum and maximum fade-out distance. If these are not zero, then they specify a range of distances from the camera over which the light is faded out. When the camera is beyond the maximum fade-out distance, the light is not rendered at all. * There is a new type of marker node called a ''shader marker'' that specifies a location at which the camera should be placed in order to precompile shaders. * The maximum number of vertices that a portal can have has been reduced from 12 to 8 for performance reasons. Any existing portals that have more than 8 vertices will automatically be reduced in size. * A new flag has been added to remote portals that forces the remote camera to be in the portal's target zone. If this flag is not specified, then the ordinary rules for determine which zone(s) contain the camera apply, but this could cause problems if the target zone is not big enough to contain all of the possible camera locations based on the location of the camera in the original zone. If the flag is specified, then the camera is guaranteed to be able to see the target zone. * Remote portals can now have shadow maps disabled as a performance optimization. When shadow maps are turned off for a remote portal, no lights rendered through the portal cast shadows. * A new flag has been added to the node settings that causes ambient lighting environments for subzones to be prioritized over the ambient lighting environment for the enclosing zone. This is useful when an object straddles the boundary between a subzone and its enclosing zone, but should receive the ambient lighting (including radiosity) from the subzone instead of the enclosing zone. * Two new standard instance modifiers called Enable Nodes and Disable Nodes have been added to the engine. === Effect Manager === * The <code>[http://c4engine.com/docs/EffectMgr/Effect_Render.html Effect::Render()]</code> function has been changed so that the first parameter is a pointer to a <code>FrustumCamera</code> node instead of a <code>Camera</code> node. * Flare effects can now be rendered at infinity. (In this case, the rotation radius for the flare occlusion test is not used.) * The projection-based depth offset used by marking effects can now be controlled through a new field named <code>markingOffset</code> in the <code>[http://c4engine.com/docs/EffectMgr/MarkingData.html MarkingData]</code> structure. * A marking effect can now be configured so that it doesn't clip polygons belonging to the underlying geometry to which the markings are applied. Instead, exact copies of any polygons intersecting the marking's bounding box are added to the marking effect so that the exact same coordinates are produced in viewport space. In this case, the depth offset parameter is ignored, and the marking effect is always offset by the minimum amount possible toward the camera using hardware-based polygon offset. This can have performance implications, so it should be used only when necessary to avoid Z fighting artifacts. A new flag for geometry nodes can force marking applied to them to use the new full polygon mode, and new terrain geometries will have this flag set by default. === Scripting === * Two new script methods called Activate Trigger and Deactivate Trigger have been added to the engine. These activate or deactivate a trigger node as if the script's initiator node had entered or exited the trigger volume, and the same rules apply. The behavior is a little different than simply activating a controller attached to a trigger node. * A new script method called Break Joint has been added to the engine. This simply breaks the built-in connections for a joint node so that it no longer has any influence over the rigid bodies previously attached to it. * A new script method called Remove Modifiers has been added to the engine. The method removes all modifiers of a specific type, or all modifiers regardless of type, from an instance node. This has no immediate effect when a world is running, but it does affect how the instance is reloaded from a saved game. Removing modifiers is useful in cases where an instance is originally modified in some way, but then a script reverses some of those modifications. When a saved game is reloaded, the reversed modifications would no longer be applied when the instance is loaded. * Script variables can now have a new scope called ''controller scope''. Variables with this scope retain their values between runs of the same script, but they are not shared among multiple instances of the script object. Their values are stored in the script controller, and each instance has its own copy. * There is a new type of controller called a ''distribution controller'' through which received messages can be processed by itself, by all controllers belonging to subnodes of its target, and/or all controllers belonging to connected nodes. This allows a single standard script method to effect a large set of nodes that are grouped together in some way. === Utility Library === * It is now possible to iterate over the elements of <code>List</code> and <code>Map</code> containers using range-based for loops. This functionality had previously been available only for <code>Array</code> containers. == Tools == === World Editor === * The gizmo has been redesigned and now has better functionality for moving and rotating nodes. As before, a node can be moved along a single axis by dragging the arrowheads with the move tool. The gizmo can now be used to move a node in a plane by dragging inside any of the small squares drawn near the node's origin. When the rotate tool is selected, the gizmo displays arcs that can be dragged to rotate about each of a node's local axes. All controls belonging to the gizmo light up when the cursor hovers over them, and gizmo controls always take precedence over using bounding box faces or edges to move or rotate. * All of the World Editor tool pages are now always visible, and they have been organized into five tabs named Object, Material, Earth, Instance, and Editor. The Page menu has been removed from the editor. * The Selection Mask and Visibility pages have been replaced by a new Node Management page that subsumes the previously existing functionality of both pages. The Node Management page displays a tree of all types of nodes and their subtypes. Check boxes next to each type determine the current selection mask, which now has hierarchical behavior. One or more types may also be selected in the tree, and the Show All, Hide All, and Select All buttons at the bottom of the page affect the group of selected types. * Buttons labelled Copy, Paste, and Reset have been added to the Transform page. These copy the transform, paste the transform, or reset the transform to the identity matrix for the selected node that currently has the gizmo. (The Copy Transform and Paste Transform items previously in the Edit menu have been removed.) There are also radio buttons that control whether the copy, paste, and reset operations are applied to the position only, to the rotation only, or to both. * The angle snap setting now appears in the Grid page. * In the scene graph viewport, all selection tools now behave as box selection when the mouse is clicked in the background and dragged. * In the scene graph viewport, all selection tools can now be used to reparent nodes by clicking inside a node and dragging. (Previously, only the Select and Move tool could be used to reparent nodes.) * In the Paint Page, the menu commands can now be used to associate paint spaces with instance nodes in addition to geometry nodes. * The outlines used for all volume-based objects are drawn nice and crisply in the editor now. e5bde365726574591de24aff17be6aed98090b66 Release Notes for Version 4.1 0 84 86 2023-07-15T10:17:45Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' December 25, 2014 == Core Engine == * The format of animation resources has changed in this release in order to accommodate morph weight animation. Existing animation resources need to be updated before they can be used in version 4.1. A conversion utility has been included, and it can be run by typing "updateanims" in the command console. This utility will update all <code>.anm</code> files in the <code>Data</code> directory hierarchy. ''..." wikitext text/x-wiki __NOTOC__ '''Release date:''' December 25, 2014 == Core Engine == * The format of animation resources has changed in this release in order to accommodate morph weight animation. Existing animation resources need to be updated before they can be used in version 4.1. A conversion utility has been included, and it can be run by typing "updateanims" in the command console. This utility will update all <code>.anm</code> files in the <code>Data</code> directory hierarchy. '''Be sure to make a backup of your <code>Data</code> folder before running this utility in case something goes wrong.''' * The <code>Constructable</code> and <code>Constructor</code> classes have been renamed to <code>Creatable</code> and <code>Creator</code> in order to eliminate the dual usage of the term "construct". A <code>Construct()</code> function is now used only in places where it pertains to an initialization function for an existing object, and not where it previously would create a new object and return it. In all cases when a new object is being created, the term "create" is now used. This will necessitate that each application or tool be modified at least as much as changing the <code>ConstructionApplication()</code> or <code>ConstructPlugin()</code> function to <code>CreateApplication()</code> or <code>CreatePlugin()</code>. * Engine support for the [[Open Data Description Language]] (OpenDDL) has been upgraded to version 1.1. This adds support for underscore separators in numerical literals, support for 16-bit floating-point values, and support for octal literals. * Due to numerous bugs in Mac OS X that violate the C++ standard's requirement that memory allocated with operator new[] be deallocated with operator delete[], the debug check in the engine for operator consistency has been disabled on the Mac. === World Manager === * The engine now supports morph geometries (also known as blend shapes). Weighted blends of multiple morph targets are calculated by a new morph controller. The skin controller is a subclass of the morph controller so that the result of the morph can be used as the bind pose mesh for skinning. * The <code>Animator</code> classes have been updated to support morph weight animation in addition to transform animation. * If a subzone does not have a fog space, shadow space, acoustics space, or radiosity space connector, then it will now inherit the corresponding space from the nearest parent zone that has a matching space connector. * The Move Connector modifier has been renamed to Move Connector Inside, and a new modifier named Move Connector Outside has been added. Both modifiers redirect an incoming connector that's hooked up to the instance node. The Move Connector Inside modifier redirects the connector to a named node inside the instanced world. The Move Connector Outside modifier redirects the connector to a node that the instance node is connected to in the main world. Since connectors in the instanced world that are connected to the root zone of the instanced world end up being connected to the instance node, the Move Connector Outside modifier can be used to connect a node inside an instanced world to a node outside, in the instancing world. === Message Manager === * Controller IDs are no longer reused after controllers are deleted, so it's no longer possible for messages to accidentally be sent to the wrong controller on client machines in a network game. === Interface Manager === * The <code>[http://c4engine.com/docs/InterfaceMgr/InterfaceMgr_SetInputManagementMode.html InterfaceMgr::SetInputManagementMode()]</code> function now updates the input mode immediately if the management mode is set to <code>kInputManagementManual</code>. It previously did not update the input mode until some change was made to the set of open windows. == Tools == === World Editor === * Options applied when importing a scene are now displayed at the bottom of the standard Import Scene dialog instead of in a separate window shown by the whichever import plugin (e.g., OpenGEX or Collada) is used to actually do the importing. These options are importing textures, merging materials, reusing named materials, and the overall scene scale. === OpenGEX Importer === * Support has been added for [[Open Game Engine Exchange | OpenGEX]] version 1.1.2. In particular, the OpenGEX Importer can now import geometries that have multiple morph targets, and it can import morph weight animation tracks. c6573326c927451e00b527a9dd69a567e292f8ac Release Notes for Version 4.2 0 85 87 2023-07-15T10:18:22Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' January 11, 2015 == Core Engine == === Graphics Manager === * Screen-space depth derivatives are now stored in the structure buffer along with the existing high-precision linear depth value. This allows for higher quality rendering along depth discontinuities, making effects such as SSAO look better. When motion blur is enabled, screen-space velocities are now stored in a separate render buffer. * Support for the Nvidia driver API has be..." wikitext text/x-wiki __NOTOC__ '''Release date:''' January 11, 2015 == Core Engine == === Graphics Manager === * Screen-space depth derivatives are now stored in the structure buffer along with the existing high-precision linear depth value. This allows for higher quality rendering along depth discontinuities, making effects such as SSAO look better. When motion blur is enabled, screen-space velocities are now stored in a separate render buffer. * Support for the Nvidia driver API has been removed from the engine. This was only used to query the driver version, and it's not worth the extra dependency. === World Manager === * A couple new performance improvements have been implemented in the morph and skin controllers. === Physics === * The movement controller, oscillation controller, rotation controller, and spin controller all have a new setting that cause them to wake up any rigid bodies that might be in their way while they're moving. When active, this would prevent a door from moving straight through a sleeping rigid body without affecting it, for example. The new setting is a flag that belongs to a new <code>KinematicController</code> base class for these controllers. * A new function called <code>CalculateWorldPositionVelocity()</code> has been added to the <code>[http://c4engine.com/docs/PhysicsMgr/RigidBodyController.html RigidBodyController]</code> class. This function is provided as a convenient way to calculate the velocity of a point on a rigid body due to the rigid body's own motion, accounting for both the linear and angular velocities. === Scripting === * The Evaluate Expression script method now accepts the same syntax that's supported by OpenDDL 1.1 for all literal types. In particular, boolean and octal literals are accepted, underscores are allowed in numerical literals, and all of the escape sequences supported by OpenDDL are available in strings and character literals. === Interface Manager === * The text button widget will no longer automatically change its alpha value based on whether it's enabled. If you want the text button's appearance to change when it's in a disabled state, you'll need to set its widget color directly. == Tools == === Model Viewer === * The Model Viewer now always creates imported animations in the same directory as the model resource regardless of where the imported files were stored. * Fixed a problem where the Model Viewer would not save a morph weight animation track. * The Model Viewer will now warn you if an animation's cue track has been modified and you attempt to close the window, select a different animation, or import a new animation without having saved the modified animation first. 39ad7a2b7d2d3450c2edb6c4b38bc65fedf07663 Release Notes for Version 4.5 0 86 88 2023-07-15T10:19:03Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' March 28, 2015 == Core Engine == * The C4 Engine now runs on iOS devices. Separate Xcode project files are included with the engine for those who have a license for mobile development. The C4 Engine currently runs on iOS devices containing an A7 or A8 processor, listed below. ** iPad Air and iPad Air 2 ** iPad Mini with Retina display and iPad Mini 3 ** iPhone 5s and iPhone 6 * Custom properties, controllers, properties, forces, modifiers..." wikitext text/x-wiki __NOTOC__ '''Release date:''' March 28, 2015 == Core Engine == * The C4 Engine now runs on iOS devices. Separate Xcode project files are included with the engine for those who have a license for mobile development. The C4 Engine currently runs on iOS devices containing an A7 or A8 processor, listed below. ** iPad Air and iPad Air 2 ** iPad Mini with Retina display and iPad Mini 3 ** iPhone 5s and iPhone 6 * Custom properties, controllers, properties, forces, modifiers, and mutators can now be preserved by the engine when a world containing them is loaded and saved while the game module that defines them is not presently active. These items are displayed with the <code>&lt;unknown&gt;</code> type in the World Editor, and they cannot be edited. === Graphics Manager === * Textures compressed on with S3TC can be used on iOS devices, but be aware that the GPU cannot decode these textures, so they are decoded in software and sent to the driver as full-size uncompressed textures. === World Manager === * Some optimizations have been made to the large-scale rendering code related to terrain and cascaded shadow mapping. * Fixed a problem in which motion blur could be rendered incorrectly if the camera is a subnode of a moving object in the scene. === Interface Manager === * Function keys F1 through F12 are now reported to keyboard event handlers using the constants <code>kKeyCodeF1</code> through <code>kKeyCodeF12</code>. * When an item in a tree widget is collapsed, any selected sub-items are now automatically unselected. * Fixed a problem that prevented Shift-Tab from working on the Mac. * There is a new configuration setting type called <code>[http://c4engine.com/docs/InterfaceMgr/InfoSetting.html InfoSetting]</code> that just displays text that cannot be edited. === Input Manager === * On Windows and Mac, the Input Manager now recognizes HID devices specifically from the following usage pages: Generic Desktop (page 0x01), Simulation (page 0x02), Sport (page 0x04), Game (page 0x05), and Keyboard/Keypad (0x07). Other types of devices, which aren't normally used for games, are intentionally ignored. * On all platforms, all input controls now have a valid 32-bit HID usage value. The high 16 bits contain the usage page, and the low 16 bits contain the usage, as defined by the HID specification. This information can be used to locate a specific control on any device and assign an action to it. * On Xbox controllers, the default behavior for the ''y'' axes of the thumb sticks has been inverted to match the default behavior of other USB controllers. * The engine supports certified wireless game controllers on iOS devices. * The <code>TouchDevice</code> class has been added to the engine to represent the touch screen on mobile devices. In gameplay mode, the touch device will generate mouse deltas when the user swipes the screen. Special touch button controls can also be added to the touch device to place virtual buttons on the screen that send ordinary button press and release events to their actions. === Sound Manager === * When a streamed sound is played, the initial load now takes place asynchronously to avoid a potential pause on the main thread. == Tools == === World Editor === * The morph controller now lets you change the default morph target weights. 998236b501faa8d1074d427f42f0574e8280d526 Release Notes for Version 5.0 0 87 89 2023-07-15T10:19:55Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' September 20, 2016 (C4 version 5.0 corresponds to Tombstone version 1.0.) == Core Engine == * All C-style casts have been changed to constructor syntax. * The <code>*</code> and <code>%</code> operators for dot product and cross product have been removed from the engine. The <code>Dot()</code> and <code>Cross()</code> functions should always be used instead. * The container modification and iteration functions have been made more verbos..." wikitext text/x-wiki __NOTOC__ '''Release date:''' September 20, 2016 (C4 version 5.0 corresponds to Tombstone version 1.0.) == Core Engine == * All C-style casts have been changed to constructor syntax. * The <code>*</code> and <code>%</code> operators for dot product and cross product have been removed from the engine. The <code>Dot()</code> and <code>Cross()</code> functions should always be used instead. * The container modification and iteration functions have been made more verbose. * In all callback-type functions, the term "proc" has been changed to "callback". * The <code>GraphEdge</code> class has been renamed to <code>GraphRelation</code>. * The <code>Singleton</code> template has been named to <code>Global</code>. * The <code>Manipulator</code> class has been renamed to <code>Director</code>. * The <code>BuildSettingList()</code> and <code>CommitSetting()</code> functions have been added to replace the <code>GetSettingCount()</code>, <code>GetSetting()</code>, and <code>SetSetting()</code> functions. * CPU timings have been added to engine, and they are displayed in the Time window. * All of the various resource formats have been updated. There is now a common header followed by resource-specific data. === World Manager === * The cell graphs into which objects are organized for each zone are now octrees instead of tall quadtrees. * Detail rings have been added to the engine. Each geometry node has a detail ring setting that determines at what distance the geometry starts to fade out. A world can have detail property that specifies the detail ring sizes. Indirect portals and camera widgets can specify a distance scale that modifies the sizes of all detail rings for geometry that is rendered through them. * A special root region graph has been added for lights to solve shadowing problems when lights are rooted in multiple zones that can see each other through portals. * The impostor system has been updated. Impostors now have better transition blends, and they are no longer required to be vertical. * The remote portal cover render stage has been removed from the engine. * Remote cameras have been renamed to indirect cameras, and remote portals have been renamed to indirect portals. * Parallel code for shadow map generation has been added to the engine to improve performance. * Multisampled rendering is now permanently on, and the engine uses a custom downsampling shader. * Infrastructure necessary for upcoming secondary frame buffer effects has been implemented. === Graphics Manager === * The motion blur effect has been improved for discontinuous screen-space velocities. * Clipping plane support has been added to vertex shaders. Clipping planes are exposed for widgets. * The engine now has the ability to reference material resources from material objects. * The fog rendering code has been enhanced. === Interface Manager === * All text rendering in the engine has been replaced with a new technology that renders glyphs directly from outline data directly on the GPU. Support for kerning and tracking have been added. === Sound Manager === * The engine now uses a new proprietary audio format. * The sound streaming code has been changed to use triple buffering. This ensures that there can be no breaks when a streaming sound loops or starts a new file. === Controllers === * The <code>Controller::ScheduleSleep()</code> function and Schedule Sleep script method have been added to the engine. * The ability now exists for a script method to delete the node to which the script is attached or one of its predecessors. === Physics === * The Shape node now supports dynamic shape substances. * The Set Shape Substance modifier has been added to the engine. === Math Library === * Custom versions of all transcendental functions and inverse trig functions have been implemented in the engine. * The various vector, bivector, and trivector classes have been improved. == Tools == === World Editor === * The [[World Editor]] now has a complete set of landscaping paint tools. * The performance of radiosity space generation has been improved by breaking the work into parallel jobs. * A new tilt setting has been added to the placement adjuster in the World Editor and [[Landscaping Editor]]. * A new director cell graph has been implemented in the [[World Editor]]. This drastically improves performance for scenes containing a lot of vegetation. * The rendering code and picking code in the [[World Editor]] have been modified to use the cell graph. Director bounding spheres have been removed. * The list of available materials in the [[World Editor]] is now displayed in the [[Material Page]], and the Material Manager has been renamed to [[Material Editor]]. * [[Material Editor]] functionality for external material resources has been added. === Script Editor === * The method appearance in the [[Script Editor]] has been changed to a larger box size. === Texture Tool === * The configuration files for [[Texture Importer]] have been updated to use the OpenDDL format. === Sound Tool === * A [[Sound Importer]] tool has been added, and it converts <code>.wav</code> files to the new format. d54e6d3d9c10b67587476c1b2b8409a1bb278a71 Release Notes for Version 5.5 0 88 90 2023-07-15T10:20:26Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' November 16, 2016 (C4 version 5.5 corresponds to Tombstone version 1.5.) == Core Engine == === Graphics Manager === * This version of the engine contains a workaround that avoids a bug in the current AMD graphics drivers. This has to do with the code that resolves the multisample frame buffer. === Interface Manager === * The appearance of the set of GUI widgets has been updated to be more crisp and to be ready for high DPI displays. Th..." wikitext text/x-wiki __NOTOC__ '''Release date:''' November 16, 2016 (C4 version 5.5 corresponds to Tombstone version 1.5.) == Core Engine == === Graphics Manager === * This version of the engine contains a workaround that avoids a bug in the current AMD graphics drivers. This has to do with the code that resolves the multisample frame buffer. === Interface Manager === * The appearance of the set of GUI widgets has been updated to be more crisp and to be ready for high DPI displays. The graphical elements used by the GUI are now stored in a single 2D array texture at <code>Data/Engine/engine/Gui.tex</code>. * Added settings to the image widget so that an array layer, depth coordinate, or cube face can be specified for 2D array, 3D, and cube map textures. * The multipane widget is now a subclass of the border widget, and the pane tabs are simply added on to an ordinary border. * A window can now directly receive mouse wheel events that are not handled by any of its subwidgets. == Tools == === Panel Editor === * The Panel Editor has received some minor updates. There are now plus and minus buttons for adding and removing mutators. === Script Editor === * Fixed a problem that would cause the Script Editor to crash if you clicked on the little arrow icon that indicates a method has an output variable assigned to it. === World Editor === * Fixed a problem that would prevent lights and sources from being rotated or resized in the viewports. * Fixed a problem that could cause geometry to be corrupted when a material replacement was undone. 568e0ebe7832eb9daae5b7364f85053e1a9fd866 Release Notes for Version 5.5.1 0 89 91 2023-07-15T10:20:53Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' December 6, 2016 (C4 version 5.5.1 corresponds to Tombstone version 1.5.1.) == Core Engine == * The API documentation has been corrected in many places to update function names in cross references. === World Manager === * New settings have been added to the Interaction property that let you specify object-space axis and angle constraints that have to be satisfied for an object to appear interactive. The direction that the camera is look..." wikitext text/x-wiki __NOTOC__ '''Release date:''' December 6, 2016 (C4 version 5.5.1 corresponds to Tombstone version 1.5.1.) == Core Engine == * The API documentation has been corrected in many places to update function names in cross references. === World Manager === * New settings have been added to the Interaction property that let you specify object-space axis and angle constraints that have to be satisfied for an object to appear interactive. The direction that the camera is looking must be within the specified angle of the selected axis or an interaction will not be detected. The angle constraint is specified as the minimum cosine of the angle between the look direction and the axis. The constraint can be disabled by selected <code>&lt;None&gt;</code> as the axis, and in that case, the Interaction property behaves as it does in previous versions. == Tools == === Texture Generation === * The texture generation code for environment maps, cube projections, spot projections, impostor textures, and radiosity spaces had been broken by changes to other parts of the engine. They now all work correctly. === World Editor === * Fixed a problem that would cause emitter volumes to disappear when you zoom in on them. c912c9b0cd1f705c1a80e57054b785b43e5f2db8 Release Notes for Version 6.0 0 90 92 2023-07-15T10:21:30Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' January 27, 2017 (C4 version 6.0 corresponds to Tombstone version 2.0.) == Core Engine == * Support for the Open Data Description Language has been updated to version 2.0. === Graphics Manager === * A few new workarounds have been implemented to deal with subtle bugs in the AMD graphics driver. === Interface Manager === * All text drawing, both in the user interface and in panel effects, now uses our new technology to render glyphs on..." wikitext text/x-wiki __NOTOC__ '''Release date:''' January 27, 2017 (C4 version 6.0 corresponds to Tombstone version 2.0.) == Core Engine == * Support for the Open Data Description Language has been updated to version 2.0. === Graphics Manager === * A few new workarounds have been implemented to deal with subtle bugs in the AMD graphics driver. === Interface Manager === * All text drawing, both in the user interface and in panel effects, now uses our new technology to render glyphs on the GPU directly from font outline data. A shader reads the quadratic Bézier curves from a special texture map for each glyph and calculates nicely antialiased edges at any resolution. The engine no longer uses texture maps to store pre-rendered bitmap versions of each glyph at one specific font size. Text is sharply rendered no matter how large it is scaled or how it is rotated. This technology anticipates the increasing ubiquity of higher DPI displays where glyphs are rendered at a higher resolution over the same physical area to achieve greater quality. * Every type of widget that draws text now has a font size setting. The font size corresponds to the height of the em square for the font. (The height of capital letters is usually around 70% of the em square height, but there is no strict rule about this.) Text widgets also have an independent scale factor, and the font size is multiplied by this scale factor to determine the final size of the glyphs that are rendered. * The text layout code in the engine now uses exact glyph advance widths to position characters, which results in fractional positioning that is correct at all font sizes. This has a much nicer appearance compared to the integral widths used by the texture-based glyphs in earlier versions of the engine. * The text layout code now also supports kerning. Using the tables contained in the original font, some pairs of glyphs are moved closer together, or sometimes further apart, to improve appearance. Kerning is enabled by default, but text widgets have a setting to disable it if desired. * Text can now have special effects applied, and they can be dynamically changed at run-time. Two effects are currently available, a shadow effect and a glow effect. * The color picker dialog now contains copy and paste buttons that operate on the current color. == Tools == === Font Importer === * The Font Importer now reads TrueType Font (<code>.ttf</code>) files directly instead of relying on the operating system to rasterize glyphs. This means that fonts can be imported on all platforms, and the results are identical on all platforms. * All Unicode values up to U+2FFFF are now support by the Font Importer, which is everything belonging to the Basic Multilingual Plane (BMP), as before, plus the Supplementary Multilingual Plane (SMP) and the Supplementary Ideographic Plane (SIP). This covers all renderable glyphs currently defined by Unicode. * When a font is imported, the settings in the Font Importer are saved to a config file so they can be restored if the font is ever imported again. This includes which ranges of glyphs are selected to be imported. === OpenGEX Importer === * Support for the OpenGEX format has been updated to version 2.0. 94fec927c6949f3def9fe018d6192eaa551d3b62 Release Notes for Version 6.1 0 91 93 2023-07-15T10:22:26Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' April 29, 2017 (C4 version 6.1 corresponds to Tombstone version 2.1.) == Core Engine == * The project files for Visual Studio have been updated to 2017. == Graphics Manager == * The engine no longer attempts to figure out how fast the GPU is in order to set defaults for all the rendering options. A single set of default options is now used for all GPUs. * By default, the engine now tries to create a 1920&times;1080 full-screen renderin..." wikitext text/x-wiki __NOTOC__ '''Release date:''' April 29, 2017 (C4 version 6.1 corresponds to Tombstone version 2.1.) == Core Engine == * The project files for Visual Studio have been updated to 2017. == Graphics Manager == * The engine no longer attempts to figure out how fast the GPU is in order to set defaults for all the rendering options. A single set of default options is now used for all GPUs. * By default, the engine now tries to create a 1920&times;1080 full-screen rendering context. If this fails, then it tries 1280&times;720 full-screen. If that fails, then the last resort is 1280&times;720 windowed. === Interface Manager === * The font format has changed in this version. Any custom fonts that were previously imported need to be imported again before they can be used. * Multicolor glyphs like emoji and pictographs are now supported in fonts that use Microsoft's layered TrueType outline method based on the <code>'COLR'</code> and <code>'CPAL'</code> tables. A new setting for text widgets enables multicolor glyph rendering, and it is on by default. If this setting is turned off, then monochrome versions of each glyph are rendered instead. * A new supersampling mode has been added to text widgets, and it renders higher-quality glyphs at a small performance cost. This is enabled by default in standalone panel resources and should usually be turned on for fonts rendered at smaller sizes. Performance is better if supersampling is turned off for larger text, and it is off by default when editing panel effects inside a world. A font must be imported with supersampling enabled for this to work. * Text widgets have another new setting for enabling two optimizations that work well for text rendered at large sizes. This setting is off by default, but it should be turned on for big text. One optimization reduces the area covered by each glyph by clipping off corners and rendering up to an eight-sided polygon instead of a simple box. A font must be imported with the geometry optimization enabled in order for this to work. The second optimization reduces computation in the font's pixel shader by enabling additional code paths, but it is only effective when text is rendered large enough to minimize shader divergence effects. This optimization is always available and does not require that a font be imported with any particular setting enabled. * The text layout code now supports glyph joining sequences and combining diacritical marks, and these can be enabled or disabled for text widgets. The joining sequences include glyph composition, which applies to things like skin tone modifiers to turn 👍&zwnj;🏽 into 👍🏽, and various types of ligatures such as the substitution of the single glyph "&#xFB01;" for the separate letters "fi". Glyph composition, standard ligatures, required ligatures, and discretionary ligatures are defined by the font being used, and they can be individually enabled or disabled when join sequences are enabled in general. * All widgets containing text now support embedded formatting directives that can change things like font size, color, tracking, and whether text is subscript or superscript. See [[Text Formatting]] for details. * The Fade and Pulsate mutators can now be used to animate the glyph effect intensity for text widgets. Only the alpha component of the color is used in this case. * On Windows, UTF-16 surrogate pairs are now supported when reading and writing the system clipboard. This applies when Unicode characters at code points U+010000 and higher are copied or pasted. === Scripts === * A special type of event method called First Execution has been added to scripts. This method generates a boolean result that is true if it's the first time that a script has been run on node to which it's attached and false otherwise. == Tools == === Font Importer === * There are now settings that can enable/disable support for kerning, join sequences, combining marks, multicolor glyphs, supersampling, and a special geometric optimization when fonts are imported. See the [[Font Importer]] page for more information. * The Font Importer can now read kerning information from the newer <code>'GPOS'</code> table in an OpenType font. If no kerning information is found there, then the older <code>'kern'</code> table is used. * The min and max glyph effect offset settings have been removed from the Font Importer. The way in which glyph effects are rendered has changed, and it's no longer necessary to specify the largest offsets in advance when a font is imported. 0964da44257264cbe5970b8d590a51a6f4283acf Release Notes for Version 6.2 0 92 94 2023-07-15T10:22:52Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' May 11, 2017 (C4 version 6.2 corresponds to Tombstone version 2.2.) == Core Engine == === Graphics Manager === * When the <code>GL_NV_alpha_to_coverage_dither_control</code> extension is available, the engine now disables dithering for alpha to coverage rendering. This gets rid of the unsightly dot pattern sometimes visible in dense alpha-tested vegetation. == Tools == === Model Viewer === * Added a scale factor to the animation impor..." wikitext text/x-wiki __NOTOC__ '''Release date:''' May 11, 2017 (C4 version 6.2 corresponds to Tombstone version 2.2.) == Core Engine == === Graphics Manager === * When the <code>GL_NV_alpha_to_coverage_dither_control</code> extension is available, the engine now disables dithering for alpha to coverage rendering. This gets rid of the unsightly dot pattern sometimes visible in dense alpha-tested vegetation. == Tools == === Model Viewer === * Added a scale factor to the animation importer so that external animations could be matched to a scaled model. * Fixed a problem that would cause the skeleton to be drawn incorrectly. === OpenGEX Importer === * Fixed a problem that could cause scenes exported from 3DS Max to be imported with the wrong transforms applied. 2cf757f33a45caa27519383eafe8ce9509b62beb Release Notes for Version 6.5 0 93 95 2023-07-15T10:23:30Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' September 30, 2017 (C4 version 6.5 corresponds to Tombstone version 2.5.) == Core Engine == === Math Library === * The vector and matrix classes have been redesigned and now have new capabilities that promote higher performance and more legible code. * Vector components can now be accessed using the swizzle syntax that's available in shading languages. For example, a 3D vector <code>v</code> can be treated as another 3D vector with its..." wikitext text/x-wiki __NOTOC__ '''Release date:''' September 30, 2017 (C4 version 6.5 corresponds to Tombstone version 2.5.) == Core Engine == === Math Library === * The vector and matrix classes have been redesigned and now have new capabilities that promote higher performance and more legible code. * Vector components can now be accessed using the swizzle syntax that's available in shading languages. For example, a 3D vector <code>v</code> can be treated as another 3D vector with its components rearranged by writing <code>v.zyx</code>. A 2D subvector can be expressed by specifying only two components as in <code>v.xy</code>. In any case, the swizzled vector is just a reference, and no data is copied, so operations on swizzled vectors run with the same performance as the original vector. Swizzles can be any combination of valid components in which there are no repeats. * Matrix classes now have special members that allow operations involving rows, columns, and transposes without any data copying. A 3&times;3 matrix has members <code>row0</code>, <code>row1</code>, <code>row2</code>, <code>col0</code>, <code>col1</code>, and <code>col2</code> that act like 3D vectors. There is also a special member <code>transpose</code> that acts like another 3D matrix whose entries are transposed. A 4&times;4 matrix has additional members <code>row3</code>, <code>col3</code>, <code>matrix3D</code>, and <code>transpose3D</code>. These last two members access the upper-left 3&times;3 matrix without any data copying. === Interface Manager === * The font format has changed in this version. Any custom fonts that were previously imported need to be imported again before they can be used. * The rendering speed, visual quality, and layout capabilities of text have all been significantly improved in this version of the engine, and they match the current features of the Slug library. See the [[Text Widget]] article for information about all of the available settings. * The supersampling option for text has been removed. The font rendering algorithm is now able to produce even higher-quality results without supersampling. * The soft shadow and glow effects for text have been removed due to poor performance. A hard shadow effect and a new outline effect are now available. === Effect Manager === * A new volumetric halo effect has been added to the engine. This renders a spherical volume with a radial density attenuation function, and it accounts for the actual visual depth between the camera and any intersecting geometries. Like the shaft effects, it has a noise option to eliminate banding. == Tools == === Font Importer === * The Font Importer generates smaller resources now by eliminating duplicate contours and redundant kerning data in a font. Degenerate curves and other types of bad data are also eliminated in poor-quality fonts. All custom fonts need to be re-imported to bring them up to the current format. a725a97f41de15637103abb16e9368841e881cf6 Release Notes for Version 6.9 0 94 96 2023-07-15T10:24:06Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' November 2, 2018 (C4 version 6.9 corresponds to Tombstone version 2.9.) * The file formats have been updated a little bit in this version. While it's not a requirement, you ''may'' upgrade your resources to the newer formats by typing <code>updateworlds</code> in the [[Command Console]]. '''Always backup your entire Data folder before doing this just in case something goes wrong.''' == Core Engine == * All of the unsigned integer types t..." wikitext text/x-wiki __NOTOC__ '''Release date:''' November 2, 2018 (C4 version 6.9 corresponds to Tombstone version 2.9.) * The file formats have been updated a little bit in this version. While it's not a requirement, you ''may'' upgrade your resources to the newer formats by typing <code>updateworlds</code> in the [[Command Console]]. '''Always backup your entire Data folder before doing this just in case something goes wrong.''' == Core Engine == * All of the unsigned integer types that previously began with <code>unsigned_</code> have been changed to begin simply with <code>u</code>. For example, <code>unsigned_int32</code> is now just <code>uint32</code>. * The <code>Array::FindArrayElement()</code> function has been renamed to <code>Array::FindArrayElementIndex()</code> to make it clear what kind of information is returned. === Graphics Manager === * The Graphics Manager on Windows and Linux now require OpenGL 3.3 plus the <code>GL_ARB_clip_control</code>, <code>GL_ARB_direct_state_access</code>, <code>GL_ARB_multi_bind</code>, <code>GL_ARB_texture_storage</code>, and <code>GL_ARB_texture_storage_multisample</code> extensions. Since Apple does not support some of these extensions (and never will), this means that C4 2.9 does not run on the Mac. * The projection matrices used by the engine have been modified to produce device-space ''z'' coordinates in the range [0,1] with reversed depth. This greatly increases depth buffer precision and eliminates Z fighting artifacts when parallel surfaces near each other are viewed from far away. * Generalized depth offset modifications and depth bounds test optimizations have been implemented to handle oblique near plane projections. This can improve the appearance of decals in reflection or refraction images, and it can improve performance of point/cube/spot light sources in reflection or refraction images. * The motion blur algorithm has been improved and now generates better results. The velocity buffer has been changed to a two-channel format using 8 bits per channel, using half the space it previously used. * The method used to split linear 32-bit depths into two 16-bit depths for the floating-point structure buffer has been improved. This gives better precision farther from the camera position. === Interface Manager === * The font format has changed in this version. Any custom fonts that were previously imported must be imported again before they can be used. * There are many new text rendering capabilities, including underline, strikethrough, horizontal stretch, transform-based subscript/superscripts, right-to-left writing directions, bidirectional layout, adaptive supersampling, rectangle primitives, fraction formatting, and hyphen-minus substitution. Settings have been added to the [[Text Widget]] that can be used to enable these in the [[Panel Editor]], and new [[Text Formatting | embedded format directives]] have been added to control them within a block of text. See the [http://sluglibrary.com/SlugManual.pdf Slug User Manual] for details about all of the text rendering features. === Effect Manager === * A new [[Text Effect]] node has been added to the engine. This is used to place text on surfaces within a game world and apply materials to the glyphs so they appear to be painted on the surfaces. (This is completely different from using text in a panel effect.) === Terrain === * The functions that build terrain geometry have been improved so that vertex sharing occurs as often as possible. Rebuilding terrain geometries can reduce the data size by roughly 5&ndash;10%. == Tools == === Font Importer === * The [[Font Importer]] contains new settings for the size and position of underline and strikethrough decorations and the transforms for subscripts and superscripts. These are initialized to the values specified in the input TrueType font file. == Tutorials == * Two basic game projects called SimpleBall and SimpleChar are now included with the engine. See [[Simple Games]]. * Several new tutorial worlds are included in the <code>Data/Tutorial</code> folder. Some of them are starting points for [[:Category:Tutorials | tutorial articles]] on the wiki. 8bb6ca2a4b89e1a183b66d247417a3d5108cceb0 Release Notes for Version 7.0 0 95 97 2023-07-15T10:25:30Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' March 22, 2023 == Core Engine == * The <code>Color4C</code> class has been renamed to [http://c4engine.com/docs/Math/Color4U.html <code>Color4U</code>] to reflect the fact that it has unsigned components. There are also new classes called [http://c4engine.com/docs/Math/Color2U.html <code>Color2U</code>], [http://c4engine.com/docs/Math/Color2S.html <code>Color2S</code>], and [http://c4engine.com/docs/Math/Color4S.html <code>Color4S</code>],..." wikitext text/x-wiki __NOTOC__ '''Release date:''' March 22, 2023 == Core Engine == * The <code>Color4C</code> class has been renamed to [http://c4engine.com/docs/Math/Color4U.html <code>Color4U</code>] to reflect the fact that it has unsigned components. There are also new classes called [http://c4engine.com/docs/Math/Color2U.html <code>Color2U</code>], [http://c4engine.com/docs/Math/Color2S.html <code>Color2S</code>], and [http://c4engine.com/docs/Math/Color4S.html <code>Color4S</code>], where the number 2 or 4 indicates the number of channels, and the letter U or S indicates unsigned or signed. * Support for the Open Data Description Language (OpenDDL) has been updated to version 3.0. * The unbounded string class <code>String&lt;&gt;</code> can now store any string that occupies 16 bytes or less (including terminator) without having to allocate additional memory. === Graphics Manager === * Complete support for proper sRGB color handling has been implemented throughout the engine. * The engine now renders into a 16-bit floating-point multisampled frame buffer to support HDR lighting. Tone mapping occurs when this frame buffer is resolved into the a single-sampled image. * Histogram-based exposure has been added to the engine. This uses a compute shader to calculate an average log luminance of the scene from which an exposure scale is derived. The luminances of the final render are scaled by this amount before tone mapping is applied. Special effects are counter-exposed by the reciprocal of the exposure scale of the previous frame so they don't become insanely bright in dark scenes. * The term ''radiosity'' has been replaced by ''illuminance'' to reflect the fact that we are dealing with visible light, and not general radiation. * The format of illuminance spaces has been changed so that color luminance is stored in an RGB9E5 texture format, allowing high dynamic range. Chromaticity is now stored in an RGBA4444 texture format, and there is a 1:1 correspondence with each luminance sample. * The game rendering resolution has been decoupled from the resolution of the display. The world is now rendered at a fixed resolution, specified by the application or chosen by the user, and scaled to the size of the window or display. The user interface is always rendered on top at the full display resolution. * Many of the rendering techniques in the engine have been improved. These include screen-space ambient occlusion, parallax mapping, cascaded shadow maps, and halo effects. The details about how most of these work can be found in [https://foundationsofgameenginedev.com/ ''Foundations of Game Engine Development, Volume 2: Rendering''] (FGED2). * A new atmospheric shadowing effect has been added to the engine. This renders light beams / god rays using the information in the cascaded shadow map. This technique is also described in detail in FGED2. * Wherever possible, shading now takes place in a coordinate system aligned to the world-space axes. * The shader LOD capabilities have been removed from the engine. They were rarely worth the effort. === Animation === * The engine now supports dual quaternion skinning. This can be enabled in the [[Skin Controller]] to perform higher quality vertex interpolation that tends to preserve volume better at a slightly higher computational cost. === Interface Manager === * The full capabilities of [[Slug]] 6.5 have been integrated into the engine. All text goes through Slug, and widgets for icons and picture albums are available. * Mutators have been renamed to [[Sprockets]]. Sprockets are attached to widgets in order to animate them in some way. === Effect Manager === * There are new icon and picture effects that can be used to apply Slug-based content to other surfaces. === World Manager === * The impostor system has received a major upgrade. == Tools == === World Editor === * All editor icons have been updated to vector graphics. * Paint space now support flow maps. These can be drawn in the World Editor using the new tools in the [[Paint Page]]. * When illuminance spaces are being generated, the overall progress is now shown in taskbar. === Texture Tool === * The texture import tool has been divided into two parts, one that handles ordinary texture maps and one that handles normal, parallax, and horizon maps. There are different console commands, <code>itexture</code> and <code>inormal</code>, to invoke these importers. === Shader Editor === * Interpolant processes are now colored blue to make them easier to identify in a shader graph. * The Minimum and Maximum processes can now take an optional third operand. If three operands are supplied, then the result is the least or greatest of all three inputs. === Font Importer === * Font importing capabilities have been upgraded to [[Slug]] 6.5. In particular, <code>.otf</code> files are supported in addition to <code>.ttf</code> files. == In Progress == There are several new features that are in progress as of this release: * The engine is transitioning from OpenGL to Vulkan. Some code is present in version 7.0, but it is not complete. * A new physically-based metallic material attribute is in progress. * A new fur shader is in progress. * The way that terrain is textured is being updated. fe81e15bea8bb290bb2442cc22f595465dc42824 Release Notes for Version 7.1 0 96 98 2023-07-15T10:26:51Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' April 24, 2023 == Core Engine == * Luminance and chromaticity have been separated for most things that emit light. This applies to light sources, emission attributes, and several special effects. This essentially allows color to be chosen independently of brightness, which can be much higher than 1.0. Brightness is now measured in physical quantities appropriate for the type of object. Infinite lights have illuminance measured in kilolux (..." wikitext text/x-wiki __NOTOC__ '''Release date:''' April 24, 2023 == Core Engine == * Luminance and chromaticity have been separated for most things that emit light. This applies to light sources, emission attributes, and several special effects. This essentially allows color to be chosen independently of brightness, which can be much higher than 1.0. Brightness is now measured in physical quantities appropriate for the type of object. Infinite lights have illuminance measured in kilolux (klx), point lights have luminous intensity measured in kilocandelas (kcd), and emissive objects have luminance measured in kilocandelas per square meter (kcd/m²). * The <code>ColorRGBA</code> class is now a subclass of the <code>ColorRGB</code> class. === Graphics Manager === * The reflection and refraction buffer formats have been changed to 16-bit floating-point. === Interface Manager === * The default GUI has been updated to a dark theme, and default font sizes have been made a little larger. === Math Library === * Functions for transforming objects with quaternions, motors (dual quaternions), and flectors have faster implementations in this release. == In Progress == There are several new features that are in progress as of this release: * The engine is transitioning from OpenGL to Vulkan. Some code is present in version 7.1, but it is not complete. * A new physically-based metallic material attribute is in progress. * A new fur shader is in progress. * The way that terrain is textured is being updated. 62cb347ace3de9d9b64dc46c27d5974906983173 C4 Menu 0 97 99 2023-07-15T10:30:15Z Eric Lengyel 1 Created page with "The '''C4 Menu''' is opened by clicking on the skull logo in the bottom-left corner of the screen. It contains several commands that are built into the core engine as well as commands that access the plugin tools. Most of these menu commands also have equivalent console commands that can be typed into the [[Command Console]]. {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|'''New&nbsp;World'''|Opens the [[World Editor]] with a new blank world. You can type..." wikitext text/x-wiki The '''C4 Menu''' is opened by clicking on the skull logo in the bottom-left corner of the screen. It contains several commands that are built into the core engine as well as commands that access the plugin tools. Most of these menu commands also have equivalent console commands that can be typed into the [[Command Console]]. {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|'''New&nbsp;World'''|Opens the [[World Editor]] with a new blank world. You can type Ctrl-N when any major window is being displayed to create a new world.}} |- {{Tablerow|'''Open&nbsp;World...'''|Opens an existing world in the [[World Editor]]. A dialog is displayed from which a <code>.wld</code> file can be chosen. You can type Ctrl-O when any major window is being displayed to open a world.}} |- {{Tablerow|'''Reopen&nbsp;Played&nbsp;World'''|Reopens a world in the [[World Editor]] that was previous played by using the '''Save and Play''' command in the editor. This command is not available until a world has been played from the editor. You can type Ctrl-Shift-P when any major window is being displayed to reopen a played world.}} |- {{Tablerow|'''Open&nbsp;Model...'''|Opens an existing model resource in the [[Model Viewer]]. A dialog is displayed from which an <code>.mdl</code> file can be chosen.}} |- {{Tablerow|'''New&nbsp;Panel'''|Opens the [[Panel Editor]] with a new blank user interface panel.}} |- {{Tablerow|'''Open&nbsp;Panel...'''|Opens an existing user interface panel in the [[Panel Editor]]. A dialog is displayed from which a <code>.pan</code> file can be chosen.}} |- {{Tablerow|'''New&nbsp;Material'''|Opens the [[Material Editor]] with a new material.}} |- {{Tablerow|'''Open&nbsp;Material...'''|Opens an existing material in the [[Material Editor]]. A dialog is displayed from which an <code>.mtl</code> file can be chosen.}} |- {{Tablerow|'''Import&nbsp;Font...'''|Opens the [[Font Importer]] for creating a new font resource.}} |- {{Tablerow|'''Open&nbsp;Sound...'''|Opens an existing sound resource in the [[Sound Player]]. A dialog is displayed from which an <code>.snd</code> file can be chosen.}} |- {{Tablerow|'''Import&nbsp;Sound...'''|Opens the [[Sound Importer]] for creating a new sound resource.}} |- {{Tablerow|'''Import&nbsp;String&nbsp;Table...'''|Displays a dialog from which a <code>.txt</code> file can be chosen and creates a new string table resource with the [[String Importer]] tool.}} |- {{Tablerow|'''Open&nbsp;Texture...'''|Opens an existing texture resource in the [[Texture Viewer]]. A dialog is displayed from which a <code>.tex</code> file can be chosen.}} |- {{Tablerow|'''Import&nbsp;Texture...'''|Opens the [[Texture Importer]] for creating a new texture resource.}} |- {{Tablerow|'''Generate&nbsp;Terrain&nbsp;Palette...'''|Opens the [[Terrain Palettes | Terrain Palette]] window for creating a new terrain texture palette resource.}} |- {{Tablerow|'''Generate&nbsp;Textures...'''|Opens the [[Texture Generation]] tool, which renders textures for light projections, environment maps, and impostor textures. (This can only be invoked while a game world is running.)}} |- {{Tablerow|'''Open&nbsp;Movie...'''|Opens an existing movie resource in the [[Movie Player]]. A dialog is displayed from which an <code>.mvi</code> file can be chosen.}} |- {{Tablerow|'''Import&nbsp;Movie...'''|Opens the [[Movie Importer]] for creating a new movie resource.}} |- {{Tablerow|'''Command&nbsp;Console'''|Opens the [[Command Console]].}} |- {{Tablerow|'''Time&nbsp;Window'''|Opens the time window, which displays the frame rate and other timing information.}} |- {{Tablerow|'''Stats&nbsp;Window'''|Opens the engine stats window, which displays various information about tasks the engine is performing.}} |- {{Tablerow|'''Networking&nbsp;Window'''|Opens the networking window, which displays information about network traffic.}} |- {{Tablerow|'''Take&nbsp;Screenshot'''|Takes a screenshot and places it in the user's Documents folder. (See [[File Locations]].)}} |- {{Tablerow|'''Quit'''|Quits the engine. You can type Ctrl-Q when any major window is being displayed to quit.)}} |} == See Also == * [[Command Console]] 36fa2568adb18c09328de9479e26ebadacc8aa53 Template:Tablehead 10 98 100 2023-07-15T10:30:33Z Eric Lengyel 1 Created page with "| style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 24px 2px 6px;" | {{{1}}} | style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 6px 2px 6px;" | {{{2}}}" wikitext text/x-wiki | style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 24px 2px 6px;" | {{{1}}} | style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 6px 2px 6px;" | {{{2}}} d468f3588442ec01a7a9d8dbc50a363389f47f60 Template:Tablerow 10 99 101 2023-07-15T10:30:56Z Eric Lengyel 1 Created page with "| style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 24px 2px 6px;" | {{{1}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{2}}}" wikitext text/x-wiki | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 24px 2px 6px;" | {{{1}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{2}}} 8f4e1061ba6dbea3733f78e88af0522c78e555dc File:Console.png 6 100 102 2023-07-15T10:32:29Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Command Console 0 101 103 2023-07-15T10:35:38Z Eric Lengyel 1 Created page with "[[File:Console.png|480px|right]] The '''Command Console''' window can be opened at any time by pressing the tilde/grave key. (On some non-English keyboards, the key directly below the Escape key should be used.) The window displays a command line and an output buffer as shown in the image to the right. If the C4 Engine was built using the debug settings, the window displays "(Debug)" to the right of the build number. The console stores a small command history that can b..." wikitext text/x-wiki [[File:Console.png|480px|right]] The '''Command Console''' window can be opened at any time by pressing the tilde/grave key. (On some non-English keyboards, the key directly below the Escape key should be used.) The window displays a command line and an output buffer as shown in the image to the right. If the C4 Engine was built using the debug settings, the window displays "(Debug)" to the right of the build number. The console stores a small command history that can be accessed with the up and down arrow keys. __TOC__ <br clear="right" /> == Core Engine Commands == The following table describes some of the commands that are built into the engine. New commands can be added by an application or plugin module (see below). {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|<code>address</code>|Displays the IP address of the local machine. Must be in a network game.}} |- {{Tablerow|<code>bind</code> ''key'' <code>"</code>''command''<code>"</code>|Binds the key whose name is ''key'' to the command specified by ''command''. Whenever the bound key is pressed in gameplay mode, the specified command is executed.}} |- {{Tablerow|<code>body</code>|Toggles the display of bounding boxes for active rigid bodies.}} |- {{Tablerow|<code>cmd</code>|Displays a list of available console commands.}} |- {{Tablerow|<code>disconnect</code>|Disconnects from a multiplayer game.}} |- {{Tablerow|<code>dump</code>|Writes a list of all currently allocated memory blocks to the file <code>Memory.txt</code>. Leak detection must be turned on.}} |- {{Tablerow|<code>exec</code> ''path''|Executes the file <code>Data/*/''path''.cfg</code>.}} |- {{Tablerow|<code>gentex</code>|Opens the [[Texture Generation]] tool, which renders textures for light projections, environment maps, and impostor textures. (Can only be invoked while a game world is running.)}} |- {{Tablerow|<code>heap</code>|(Advanced) Displays memory heap totals in the console.}} |- {{Tablerow|<code>load</code> ''name''|Loads the world <code>''name''.wld</code> for gameplay.}} |- {{Tablerow|<code>lrgn</code>|(Advanced) Toggles the display of light regions.}} |- {{Tablerow|<code>net</code>|Opens the Network window, which displays various network statistics. (The Network window can also be opened by choosing '''C4 > Network Window'''.)}} |- {{Tablerow|<code>norm</code>|Toggles the display of normal vectors.}} |- {{Tablerow|<code>quit</code>|Quits the C4 Engine.}} |- {{Tablerow|<code>record</code> ''name''|Starts recording video and/or audio to files that can later be imported as a movie. See [[Recording Movies]] for more information.}} |- {{Tablerow|<code>resolve</code> ''hostname''|Resolves a host name to an IP address. Must be in a network game.}} |- {{Tablerow|<code>restore</code> ''name''|Restore the previously saved game <code>Save/''name''.sav</code>.}} |- {{Tablerow|<code>save</code> ''name''|Save the current game as <code>Save/''name''.sav</code>.}} |- {{Tablerow|<code>say</code> <code>"</code>''message''<code>"</code>|Sends a chat message to all players in the current multiplayer game.}} |- {{Tablerow|<code>shot</code> ''name''|Takes a [[Screenshots|screenshot]] and saves it as <code>''name''.tga</code> in the user's Documents directory in a subfolder named C4 Engine. If a <code>#</code> character appears in the name, then the name from that point on is replaced with a screenshot count that starts at 1 and gets incremented each time it is used in a screenshot name.}} |- {{Tablerow|<code>smap</code> ''type''|(Advanced) Opens the Shadow Map window for a particular light type. The value of ''type'' must be <code>inft</code>, <code>pont</code>, or <code>spot</code>.}} |- {{Tablerow|<code>spth</code>|(Advanced) Toggles the display of sound flow paths.}} |- {{Tablerow|<code>stat</code>|Opens the Stats window, which displays various engine statistics. (The Stats window can also be accessed by choosing '''C4 > Stats Window'''.)}} |- {{Tablerow|<code>tang</code>|Toggles the display of tangent vectors.}} |- {{Tablerow|<code>time</code>|Opens the Time window, which displays the frame rate in frames/s and ms/frame, the current load on the GPU and CPU, and a detailed breakdown of the time the engine spends on specific features such as shadows and post processing. (The Time window can also be opened by choosing '''C4 > Time Window'''.)}} |- {{Tablerow|<code>unbind</code> ''key''|Unbinds the key whose name is ''key''.}} |- {{Tablerow|<code>undef</code> ''name''|Undefines the variable ''name'', if the variable is not permanent.}} |- {{Tablerow|<code>unload</code>|Unloads the current gameplay world.}} |- {{Tablerow|<code>var</code>|Displays a list of currently defined system variables.}} |- {{Tablerow|<code>wire</code>|Toggles the display of the wireframe overlay.}} |} == Tool Commands == The following commands are defined by the standard tools that ship with the C4 Engine. Most of these commands have equivalent items in the [[C4 Menu]]. If the ''name'' parameter is omitted from any of these commands, then a file picker dialog will appear to let you select a file. {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|<code>ifont</code>|Opens the [[Font Importer]] tool. (This tool can also be opened by choosing '''C4 > Import Font'''.)}} |- {{Tablerow|<code>imovie</code>|Opens the [[Movie Importer]] tool. (Movies can also be imported by choosing '''C4 > Import Movie'''.)}} |- {{Tablerow|<code>isound</code> ''name''|Imports the sound file <code>''name''.wav</code>. See also [[Sound Importer]]. (Sounds can also be imported by choosing '''C4 > Import Sound'''.)}} |- {{Tablerow|<code>istring</code> ''name''|Imports the string table file <code>''name''.txt</code>. See also [[String Tables]]. (String tables can also be imported by choosing '''C4 > Import String Table'''.)}} |- {{Tablerow|<code>itexture</code> ''name''|Imports the texture file <code>''name''.tga</code>. See also [[Texture Importer]]. (Textures can also be imported by choosing '''C4 > Import Texture'''.)}} |- {{Tablerow|<code>model</code> ''name''|Opens the model file <code>''name''.mdl</code> in the [[Model Viewer]] tool. (Models can also be opened by choosing '''C4 > Open Model'''.)}} |- {{Tablerow|<code>movie</code> ''name''|Opens the movie file <code>''name''.mvi</code> in the [[Movie Player]] tool. (Movies can also be opened by choosing '''C4 > Open Movie'''.)}} |- {{Tablerow|<code>pack</code> ''name''|Creates a pack file, where ''name'' is the name of a top-level subfolder in the <code>Data</code> directory. See also [[Pack Files and Virtual Directories]].}} |- {{Tablerow|<code>panel</code> ''name''|Opens the panel file <code>''name''.pan</code> in the [[Panel Editor]] tool. (Panels can also be opened by choosing '''C4 > Open Panel'''.)}} |- {{Tablerow|<code>sound</code> ''name''|Opens the sounds file <code>''name''.snd</code> in the [[Sound Player]] tool. (Sounds can also be opened by choosing '''C4 > Open Sound'''.)}} |- {{Tablerow|<code>texture</code> ''name''|Opens the texture file <code>''name''.tex</code> in the [[Texture Viewer]] tool. (Textures can also be opened by choosing '''C4 > Open Texture'''.)}} |- {{Tablerow|<code>world</code> ''name''|Opens the world file <code>''name''.wld</code> in the [[World Editor]] tool. (Worlds can also be opened by choosing '''C4 > Open World'''.)}} |} == Defining New Commands == Application modules and plugin modules can add their own commands to the engine by creating new instances of the <code>Command</code> class. The constructor for the <code>Command</code> class takes a command string and a pointer to an observer object that is invoked when the command is executed. For example, to define a command called explode that causes the <code>MyClass::ExplodeFunction()</code> function to be called, you would construct a new <code>Command</code> instance as follows. <source lang="c++"> CommandObserver<MyClass> explodeObserver(this, &MyClass::ExplodeFunction); Command *explodeCommand = new Command("explode", &explodeObserver); </source> Once the command has been constructed, it needs to be added to the engine's command list before it will be recognized. This is done by calling the <code>Engine::AddCommand()</code> function. Continuing the explode example, you would make the following call to add the explode command to the engine. <source lang="c++"> TheEngine->AddCommand(explodeCommand); </source> Destroying the <code>Command</code> instance automatically removes the command from the engine. The observer event handling function assigned to a new command must have the following prototype. <source lang="c++"> void ExplodeFunction(Command *command, const char *text); </source> When a command is entered into the console (or executed from a file), the observer event handler is invoked, and the text passed in through the text parameter provides the rest of the command line. For instance, the command <code>explode 1 boom</code> would cause the <code>ExplodeFunction()</code> function to be called with a pointer to the string <code>"1 boom"</code>. == Console Output == You can write text to the Command Console window by calling the <code>Engine::Report()</code> function. The string passed to the <code>Engine::Report()</code> function is output to the console whenever the <code>flags</code> parameter does not include the bit <code>kReportLog</code>. For example, to write some integer value to the console with a text label, you could make the following call: <source lang="c++"> Engine::Report(String<63>("My value is now ") += myValue); </source> (The number 63 represents the maximum length of the string stored in the <code>String</code> object. This number can be omitted altogether to get an arbitrarily large string, but it causes extra memory allocations.) == Disabling the Console == The Command Console window can be opened when the keyboard is in either interface mode or game input mode, and both of these methods must be disabled in order to prevent access to the console. To make the Command Console window completely inaccessible, make the following two function calls: <source lang="c++"> TheInputMgr->SetConsoleCallback(nullptr); TheInterfaceMgr->DisableConsole(); </source> If the Command Console window is later going to be enabled again, then it will also be necessary to save the previous console procedure so that it can be restored. This can be done by expanding the above code as follows: <source lang="c++"> // Declared in some larger scope: InputMgr::KeyCallback savedConsoleCallback; void *savedConsoleCookie; ... savedConsoleCallback = TheInputMgr->GetConsoleCallback(); savedConsoleCookie = TheInputMgr->GetConsoleCookie(); TheInputMgr->SetConsoleCallback(nullptr); TheInterfaceMgr->DisableConsole(); </source> To enable the Command Console window again and restore the previous console procedure in the Input Manager, use the following code: <source lang="c++"> TheInputMgr->SetConsoleProc(savedConsoleProc, savedConsoleCookie); TheInterfaceMgr->EnableConsole(); </source> == See Also == * [[C4 Menu]] * [[List of System Variables]] d6849f31a22f5bf4d99ce8200cce85534cfde394 Pack Files and Virtual Directories 0 102 104 2023-07-15T10:36:58Z Eric Lengyel 1 Created page with "The Resource Manager supports pack files and a virtual directory hierarchy. All resources are stored inside the <code>Data</code> folder, where resources can be organized in an arbitrary manner. However, the top-level contents of the <code>Data</code> folder have special meanings. All of the top-level sub-folders of the <code>Data</code> folder behave as if their contents belonged to a single virtual folder at the root of the resource name space. These top-level subfold..." wikitext text/x-wiki The Resource Manager supports pack files and a virtual directory hierarchy. All resources are stored inside the <code>Data</code> folder, where resources can be organized in an arbitrary manner. However, the top-level contents of the <code>Data</code> folder have special meanings. All of the top-level sub-folders of the <code>Data</code> folder behave as if their contents belonged to a single virtual folder at the root of the resource name space. These top-level subfolders exist only for external organization and do not participate in the unique identification of any resources. As an example, suppose that there existed two subfolders <code>Data/Interiors/</code> and <code>Data/Exteriors/</code>. A resource named <code>Wood.tex</code> could be stored in either subfolder, but it would still be identified only as <code>Wood</code> by the Resource Manager. The name of the top-level subfolder is not part of the resource's path. However, if the <code>Wood.tex</code> resource was placed in an additional subfolder such as <code>Data/Exteriors/Forest/</code>, then the name of the resource would be <code>Forest/Wood</code>. All folder names beneath the top-level subfolders of the <code>Data</code> directory are part of the resource name. The resources that ship with the C4 Engine have been divided into the following subfolders: * A folder named <code>Engine</code> that contains the resources used by the core engine and required by all applications. * A folder named <code>Tools</code> that contains the resources used exclusively by the tool plugins. * A folder named <code>Demo</code> that contains the resources used exclusively by the demo worlds. * A folder named <code>The31st</code> that contains the resources used by our game [http://the31stgame.com/ ''The 31st'']. Pack files, having the extension <code>.pak</code>, can also be stored at the top level of the <code>Data</code> directory. A pack file is created by using the [[Resource Packer]] tool to pack the contents of a top-level subfolder into a single file. The console command <code>pack ''name''</code> is used to create a pack file, where ''name'' is the name of a top-level subfolder. For example, the command <code>pack Demo</code> will create the file <code>Demo.pak</code> containing all of the resources used exclusively by the Demo worlds. Once a pack file has been created, the folder from which it was made can be deleted, and the Resource Manager will then fetch resources from the pack file. (The pack file takes precedence over the folder from which it was created.) Folders and pack files are the only items allowed at the top level of the <code>Data</code> directory. Other types of files in that location are ignored. Because concealment is a benefit provided by pack files, there will not be an unpacking tool that would allow users to easily extract resources from a <code>.pak</code> file. Pack files take precedence in reverse lexicographical order according to their names. So if a resource with the same name exists in <code>MyPatch1.pak</code> and <code>MyPatch2.pak</code>, then the one in <code>MyPatch2.pak</code> will always be loaded because the name of the pack file comes later than <code>MyPatch1.pak</code>. == See Also == * [[Resource Packer]] 032281b89aa435e70790f535d90919e22c493798 File Locations 0 103 105 2023-07-15T10:38:38Z Eric Lengyel 1 Created page with "The following table lists the locations where certain types of files created by the C4 Engine are stored under Windows. {| {{Table}} {{Tablehead|File Type|File Location}} |- {{Tablerow|Log file|<code>C:\Users\''&lt;username&gt;''\AppData\Local\C4 Engine\</code>}} |- {{Tablerow|Configuration files|<code>C:\Users\&lt;username&gt;\AppData\Roaming\C4 Engine\</code>}} |- {{Tablerow|[[Screenshots]] and saved games|<code>C:\Users\&lt;username&gt;\Documents\C4 Engine\</code>}}..." wikitext text/x-wiki The following table lists the locations where certain types of files created by the C4 Engine are stored under Windows. {| {{Table}} {{Tablehead|File Type|File Location}} |- {{Tablerow|Log file|<code>C:\Users\''&lt;username&gt;''\AppData\Local\C4 Engine\</code>}} |- {{Tablerow|Configuration files|<code>C:\Users\&lt;username&gt;\AppData\Roaming\C4 Engine\</code>}} |- {{Tablerow|[[Screenshots]] and saved games|<code>C:\Users\&lt;username&gt;\Documents\C4 Engine\</code>}} |} Here, <code>''&lt;username&gt;''</code> should be replaced with the login name of the current user. The <code>AppData</code> directory is not visible unless you show hidden files and folders (in '''Folders Options''' under the '''View''' tab). == Log File == Every time the C4 Engine runs, it creates a log file in HTML format named <code>C4-Log.html</code>. The file is placed in the directory designated by the operating system for per-user local application support files. == Configuration Files == When the user changes the game settings, the configuration files <code>engine.cfg</code> and <code>input.cfg</code> are saved to the directory designated by the operating system for per-user roaming application support files. == Screenshots and Saved Games == [[Screenshots]] and saved games are stored in the user's documents directory. 9e7b75b0908033d8632c005a7683fb85ebc502dc String Tables 0 104 106 2023-07-15T10:39:07Z Eric Lengyel 1 Created page with "'''String tables''' are used by the C4 Engine to store human-readable text strings in resources that are external to the engine code and game code. The use of string tables is not required, but they can be convenient for storing strings separately in order to make localization easy and allow text to be changed without the need to recompile your game. == String Table Resources == String table resources have the <code>.str</code> file extension and reside inside subfolde..." wikitext text/x-wiki '''String tables''' are used by the C4 Engine to store human-readable text strings in resources that are external to the engine code and game code. The use of string tables is not required, but they can be convenient for storing strings separately in order to make localization easy and allow text to be changed without the need to recompile your game. == String Table Resources == String table resources have the <code>.str</code> file extension and reside inside subfolders of the <code>Data</code> directory. These files are stored in a binary format and are created by using the [[String Importer]] tool to import text files from the <code>Import</code> directory. A string table resource is loaded by constructing a <code>StringTable</code> class with the name of the resource, omitting the top-level folder name inside the <code>Data</code> folder. Strings can be retrieved from the string table by calling the <code>StringTable::GetString()</code> function with a <code>StringID</code> object containing the identifier(s) for the string. For example, a string having the identifier <code>'type'</code> can be retrieved using the following code. const char *string = stringTable->GetString(StringID('type')); A string nested within a hierarchy can be retrieved by adding more types to the <code>StringID</code> object as in the following code. const char *substring = stringTable->GetString(StringID('type', 'abcd')); Up to five identifiers can be specified. == See Also == * [[String Importer]] ca784393a8f667f9dfb76122eba27dfc77fd73ce Movement Controller 0 105 107 2023-07-15T10:40:18Z Eric Lengyel 1 Created page with "__NOTOC__ The '''Movement Controller''' is a type of controller that causes a node to move forward and backward between two positions. The Movement Controller is built into the core engine, and it is one of four ''kinematic'' controllers that cause an object to follow an exact motion. Rigid bodies controlled by the Physics Manager are able to interact with kinematic objects, but they cannot stop kinematic objects or alter their motions. A kinematic object pushes rigid bo..." wikitext text/x-wiki __NOTOC__ The '''Movement Controller''' is a type of controller that causes a node to move forward and backward between two positions. The Movement Controller is built into the core engine, and it is one of four ''kinematic'' controllers that cause an object to follow an exact motion. Rigid bodies controlled by the Physics Manager are able to interact with kinematic objects, but they cannot stop kinematic objects or alter their motions. A kinematic object pushes rigid bodies out of its way no matter what. == Settings == The following settings are available for Movement Controllers. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Kinematic&nbsp;Controller&nbsp;Settings'''}} |- {{Setting|'''Wake&nbsp;intersecting&nbsp;rigid&nbsp;bodies'''|Specifies whether sleeping rigid bodies in the path of the kinematic object are detected and awakened. If this is disabled, then the kinematic object will pass straight through any sleeping rigid bodies that it comes in contact with. If this is enabled, then sleeping rigid bodies that intersect the bounding box of the kinematic object are automatically awakened so they can interact with the kinematic object. For best performance, this setting should be disabled if it's known that the kinematic object will not come in contact with sleeping rigid bodies.}} |- {{HeadingSetting|'''Movement&nbsp;Controller&nbsp;Settings'''}} |- {{Setting|'''Movement speed (m/s)'''|The speed at which the target node moves between two positions, measured in meters per second.}} |- {{Setting|'''Acceleration time (s)'''|The length of time it takes for the target node to be accelerated to full speed when it starts moving.}} |- {{Setting|'''Deceleration time (s)'''|The length of time it takes for the target node to be decelerated to a stop when it stops moving.}} |- {{Setting|'''Start position connector key'''|The name of the connector attached to the target node that is connected to the start position for the movement.}} |- {{Setting|'''Finish position connector key'''|The name of the connector attached to the target node that is connected to the finish position for the movement.}} |} == Script Functions == The Movement Controller defines the following functions that can be called from a [[Script Editor | script]] using the '''Call Controller Function''' method. {| {{Table}} {{Tablehead|Function|Description}} |- {{Tablerow|'''Get Movement Speed'''|Returns the movement speed and completes immediately.}} |- {{Tablerow|'''Set Movement Speed'''|Sets the movement speed and completes immediately. * The '''Movement speed (m/s)''' setting specifies the new movement speed in meters per second.}} |- {{Tablerow|'''Move to Start Position'''|Begins moving the target node to the start position. This function completes when the target node reaches the start position.}} |- {{Tablerow|'''Move to Finish Position'''|Begins moving the target node to the finish position. This function completes when the target node reaches the finish position.}} |} == See Also == * [http://c4engine.com/docs/PhysicsMgr/MovementController.html <code>MovementController</code>] class * [[Oscillation Controller]] * [[Rotation Controller]] * [[Spin Controller]] * [[Physics]] [[Category:Physics]] [[Category:Controllers]] 5cf5b132c5bacce94382a31ea5bcd239f08d414d Template:HeadingSetting 10 106 108 2023-07-15T10:40:38Z Eric Lengyel 1 Created page with "| style="vertical-align: top; background-color: #E8E8E8; border-left: solid 1px #444; border-right: solid 1px #444; border-top: solid 2px #444; border-bottom: solid 2px #444; padding: 2px 24px 2px 6px;" | {{{1}}} | style="vertical-align: top; background-color: #E8E8E8; border-left: solid 1px #444; border-right: solid 1px #444; border-top: solid 2px #444; border-bottom: solid 2px #444; padding: 2px 6px 2px 6px;" |" wikitext text/x-wiki | style="vertical-align: top; background-color: #E8E8E8; border-left: solid 1px #444; border-right: solid 1px #444; border-top: solid 2px #444; border-bottom: solid 2px #444; padding: 2px 24px 2px 6px;" | {{{1}}} | style="vertical-align: top; background-color: #E8E8E8; border-left: solid 1px #444; border-right: solid 1px #444; border-top: solid 2px #444; border-bottom: solid 2px #444; padding: 2px 6px 2px 6px;" | 6243237439876bfe8d6636dbf85b2fc9e3728947 Template:Setting 10 107 109 2023-07-15T10:40:59Z Eric Lengyel 1 Created page with "| style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 24px 2px 6px;" | {{{1}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{2}}}" wikitext text/x-wiki | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 24px 2px 6px;" | {{{1}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{2}}} 8f4e1061ba6dbea3733f78e88af0522c78e555dc Oscillation Controller 0 108 110 2023-07-15T10:42:25Z Eric Lengyel 1 Created page with "__NOTOC__ The '''Oscillation Controller''' is a type of controller that causes a node to oscillate between two positions on a sine wave. The Oscillation Controller is built into the core engine, and it is one of four ''kinematic'' controllers that cause an object to follow an exact motion. Rigid bodies controlled by the Physics Manager are able to interact with kinematic objects, but they cannot stop kinematic objects or alter their motions. A kinematic object pushes rig..." wikitext text/x-wiki __NOTOC__ The '''Oscillation Controller''' is a type of controller that causes a node to oscillate between two positions on a sine wave. The Oscillation Controller is built into the core engine, and it is one of four ''kinematic'' controllers that cause an object to follow an exact motion. Rigid bodies controlled by the Physics Manager are able to interact with kinematic objects, but they cannot stop kinematic objects or alter their motions. A kinematic object pushes rigid bodies out of its way no matter what. == Settings == The following settings are available for Oscillation Controllers. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Kinematic&nbsp;Controller&nbsp;Settings'''}} |- {{Setting|'''Wake&nbsp;intersecting&nbsp;rigid&nbsp;bodies'''|Specifies whether sleeping rigid bodies in the path of the kinematic object are detected and awakened. If this is disabled, then the kinematic object will pass straight through any sleeping rigid bodies that it comes in contact with. If this is enabled, then sleeping rigid bodies that intersect the bounding box of the kinematic object are automatically awakened so they can interact with the kinematic object. For best performance, this setting should be disabled if it's known that the kinematic object will not come in contact with sleeping rigid bodies.}} |- {{HeadingSetting|'''Oscillation&nbsp;Controller&nbsp;Settings'''}} |- {{Setting|'''Oscillation speed (cycles/s)'''|The speed at which the target node oscillates between two positions, measured in the number of complete cycles per second. The reciprocal of this number gives the period of one full oscillation in seconds.}} |- {{Setting|'''Start position connector key'''|The name of the connector attached to the target node that is connected to the start position for the oscillation.}} |- {{Setting|'''Finish position connector key'''|The name of the connector attached to the target node that is connected to the finish position for the oscillation.}} |} == Script Functions == The Oscillation Controller defines the following functions that can be called from a [[Script Editor | script]] using the '''Call Controller Function''' method. {| {{Table}} {{Tablehead|Widget|Description}} |- {{Tablerow|'''Get Oscillation Speed'''|Returns the oscillation speed and completes immediately.}} |- {{Tablerow|'''Set Oscillation Speed'''|Sets the oscillation speed and completes immediately. * The '''Oscillation speed (cycles/s)''' setting specifies the new oscillation speed in cycles per second. * The '''Acceleration time (s)''' setting specifies the length of time, in seconds, it takes to reach the new oscillation speed.}} |} == See Also == * [http://c4engine.com/docs/PhysicsMgr/OscillationController.html <code>OscillationController</code>] class * [[Oscillation Tutorial]] * [[Movement Controller]] * [[Rotation Controller]] * [[Spin Controller]] * [[Physics]] [[Category:Physics]] [[Category:Controllers]] 38a69e36a0c08edf5f43198678487da0974a75bd Rotation Controller 0 109 111 2023-07-15T10:42:52Z Eric Lengyel 1 Created page with "__NOTOC__ The '''Rotation Controller''' is a type of controller that causes a node to rotate forward or backward through a given angle. The Rotation Controller is built into the core engine, and it is one of four ''kinematic'' controllers that cause an object to follow an exact motion. Rigid bodies controlled by the Physics Manager are able to interact with kinematic objects, but they cannot stop kinematic objects or alter their motions. A kinematic object pushes rigid b..." wikitext text/x-wiki __NOTOC__ The '''Rotation Controller''' is a type of controller that causes a node to rotate forward or backward through a given angle. The Rotation Controller is built into the core engine, and it is one of four ''kinematic'' controllers that cause an object to follow an exact motion. Rigid bodies controlled by the Physics Manager are able to interact with kinematic objects, but they cannot stop kinematic objects or alter their motions. A kinematic object pushes rigid bodies out of its way no matter what. == Settings == The following settings are available for Rotation Controllers. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Kinematic&nbsp;Controller&nbsp;Settings'''}} |- {{Setting|'''Wake&nbsp;intersecting&nbsp;rigid&nbsp;bodies'''|Specifies whether sleeping rigid bodies in the path of the kinematic object are detected and awakened. If this is disabled, then the kinematic object will pass straight through any sleeping rigid bodies that it comes in contact with. If this is enabled, then sleeping rigid bodies that intersect the bounding box of the kinematic object are automatically awakened so they can interact with the kinematic object. For best performance, this setting should be disabled if it's known that the kinematic object will not come in contact with sleeping rigid bodies.}} |- {{HeadingSetting|'''Rotation&nbsp;Controller&nbsp;Settings'''}} |- {{Setting|'''Rotation angle (deg)'''|The angle through which the target node rotates, measured in degrees.}} |- {{Setting|'''Rotation speed (deg/s)'''|The speed at which the target node rotates between two angles, measured in degrees of angle per second.}} |- {{Setting|'''Acceleration time (s)'''|The length of time it takes for the target node to be accelerated to full speed when it starts rotating.}} |- {{Setting|'''Deceleration time (s)'''|The length of time it takes for the target node to be decelerated to a stop when it stops rotating.}} |- {{Setting|'''Center position connector key'''|The name of the connector attached to the target node that is connected to the center position for the rotation. The rotation occurs about the ''z'' axis of the connected node. Positive angles represent counterclockwise rotations when the ''z'' is pointing toward you.}} |} == Script Functions == The Rotation Controller defines the following functions that can be called from a [[Script Editor | script]] using the '''Call Controller Function''' method. {| {{Table}} {{Tablehead|Function|Description}} |- {{Tablerow|'''Get Rotation Speed'''|Returns the rotation speed and completes immediately.}} |- {{Tablerow|'''Set Rotation Speed'''|Sets the rotation speed and completes immediately. * The '''Rotation speed (deg/s)''' setting specifies the new rotation speed in degrees per second.}} |- {{Tablerow|'''Rotate to Start Angle'''|Begins rotating the target node to the start angle. This function completes when the target node reaches the start angle.}} |- {{Tablerow|'''Rotate to Finish Angle'''|Begins rotating the target node to the finish angle. This function completes when the target node reaches the finish angle.}} |} == See Also == * [http://c4engine.com/docs/PhysicsMgr/RotationController.html <code>RotationController</code>] class * [[Spin Controller]] * [[Movement Controller]] * [[Oscillation Controller]] * [[Physics]] [[Category:Physics]] [[Category:Controllers]] 7ad04058f14dac7ff60bb69a4217cf3b40c0438e Spin Controller 0 110 112 2023-07-15T10:43:26Z Eric Lengyel 1 Created page with "__NOTOC__ The '''Spin Controller''' is a type of controller that causes a node to continuously spin about a particular axis. The Spin Controller is built into the core engine, and it is one of four ''kinematic'' controllers that cause an object to follow an exact motion. Rigid bodies controlled by the Physics Manager are able to interact with kinematic objects, but they cannot stop kinematic objects or alter their motions. A kinematic object pushes rigid bodies out of it..." wikitext text/x-wiki __NOTOC__ The '''Spin Controller''' is a type of controller that causes a node to continuously spin about a particular axis. The Spin Controller is built into the core engine, and it is one of four ''kinematic'' controllers that cause an object to follow an exact motion. Rigid bodies controlled by the Physics Manager are able to interact with kinematic objects, but they cannot stop kinematic objects or alter their motions. A kinematic object pushes rigid bodies out of its way no matter what. == Settings == The following settings are available for Spin Controllers. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Kinematic&nbsp;Controller&nbsp;Settings'''}} |- {{Setting|'''Wake&nbsp;intersecting&nbsp;rigid&nbsp;bodies'''|Specifies whether sleeping rigid bodies in the path of the kinematic object are detected and awakened. If this is disabled, then the kinematic object will pass straight through any sleeping rigid bodies that it comes in contact with. If this is enabled, then sleeping rigid bodies that intersect the bounding box of the kinematic object are automatically awakened so they can interact with the kinematic object. For best performance, this setting should be disabled if it's known that the kinematic object will not come in contact with sleeping rigid bodies.}} |- {{HeadingSetting|'''Spin&nbsp;Controller&nbsp;Settings'''}} |- {{Setting|'''Spin speed (rev/s)'''|The speed at which the target node spins, measured in the number of complete revolutions per second. The reciprocal of this number gives the period of one full revolution in seconds.}} |- {{Setting|'''Center position connector key'''|The name of the connector attached to the target node that is connected to the center position for the rotation. The rotation occurs about the z axis of the connected node. Positive angles represent counterclockwise rotations when the z is pointing toward you.}} |} == Script Functions == The Spin Controller defines the following functions that can be called from a [[Script Editor | script]] using the '''Call Controller Function''' method. {| {{Table}} {{Tablehead|Function|Description}} |- {{Tablerow|'''Get Spin Speed'''|Returns the spin speed and completes immediately.}} |- {{Tablerow|'''Set Spin Speed'''|Sets the spin speed and completes immediately. * The '''Spin speed (rev/s)''' setting specifies the new spin speed in revolutions per second. * The '''Acceleration time (s)''' setting specifies the length of time, in seconds, it takes to reach the new spin speed.}} |} == See Also == * [http://c4engine.com/docs/PhysicsMgr/SpinController.html <code>SpinController</code>] class * [[Rotation Controller]] * [[Movement Controller]] * [[Oscillation Controller]] * [[Physics]] [[Category:Physics]] [[Category:Controllers]] b4248db709cef887d89abb5a5cd180a87c5ee099 Rope Controller 0 111 113 2023-07-15T10:43:53Z Eric Lengyel 1 Created page with "__NOTOC__ The '''Rope Controller''' is the type of controller assigned to a dynamic rope geometry. The Rope Controller is built into the core engine, and it is part of the Physics Manager. == Settings == The following settings are available for Rope Controllers. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Deformable&nbsp;Body&nbsp;Flags'''|}} |- {{Setting|'''Ignore&nbsp;force&nbsp;fields'''|If checked, then force fields do not affect this rop..." wikitext text/x-wiki __NOTOC__ The '''Rope Controller''' is the type of controller assigned to a dynamic rope geometry. The Rope Controller is built into the core engine, and it is part of the Physics Manager. == Settings == The following settings are available for Rope Controllers. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Deformable&nbsp;Body&nbsp;Flags'''|}} |- {{Setting|'''Ignore&nbsp;force&nbsp;fields'''|If checked, then force fields do not affect this rope geometry.}} |- {{HeadingSetting|'''Time&nbsp;Settings'''|}} |- {{Setting|'''Warm&nbsp;start&nbsp;time&nbsp;interval&nbsp;(s)'''|The length of time over which the rope simulation is warmed up when a world is first loaded. This is not an actual length of time that you must wait, but it determines the number of internal simulation steps that are run as quickly as possible in order to give the rope time to reach a steady state.}} |- {{Setting|'''Invisible&nbsp;time&nbsp;before&nbsp;sleeping&nbsp;(s)'''|The length of time that a rope geometry must not be rendered before the controller automatically goes to sleep in order to save processing time. When a rope controller automatically goes to sleep, it wakes up the next time the rope geometry is rendered, except in cases when the controller has explicitly been put to sleep by the Sleep Controller script method or by the <code>Controller::Sleep()</code> function.}} |- {{HeadingSetting|'''Physical&nbsp;Properties'''|}} |- {{Setting|'''Particle&nbsp;mass&nbsp;(kg)'''|The mass of each simulated particle composing the rope. For a rope geometry, the number of simulated particles is (''w'' + 1), where ''w'' is the number of subdivisions specified in the ''x'' direction.}} |- {{Setting|'''Volume&nbsp;multiplier'''|The factor by which the volume represented by each particle is multiplied when calculating buoyant forces.}} |- {{Setting|'''Gravity&nbsp;multiplier'''|The factor by which the force of gravity is multiplied for this rope geometry.}} |- {{Setting|'''Fluid&nbsp;drag&nbsp;multiplier'''|The factor by which fluid drag forces are multiplied for this rope geometry.}} |- {{Setting|'''Wind&nbsp;drag&nbsp;multiplier'''|The factor by which wind drag forces are multiplied for this rope geometry.}} |- {{Setting|'''Internal&nbsp;resistance'''|The amount of internal resistance to motion for this rope geometry. This setting slows the velocities of the simulated particles.}} |- {{HeadingSetting|'''Spring&nbsp;Settings'''|}} |- {{Setting|'''Stretch&nbsp;spring&nbsp;coefficient'''|The spring stiffness coefficient for &ldquo;stretch&rdquo; springs, which connect adjacent particles.}} |- {{Setting|'''Bend&nbsp;spring&nbsp;coefficient'''|The spring stiffness coefficient for &ldquo;bend&rdquo; springs, which connect particles that are two positions apart.}} |- {{HeadingSetting|'''Damper&nbsp;Settings'''|}} |- {{Setting|'''Stretch&nbsp;damper&nbsp;coefficient'''|The spring damping coefficient for &ldquo;stretch&rdquo; springs, which connect adjacent particles.}} |- {{Setting|'''Bend&nbsp;damper&nbsp;coefficient'''|The spring damping coefficient for &ldquo;bend&rdquo; springs, which connect particles that are two positions apart.}} |- {{HeadingSetting|'''Attachment&nbsp;Settings'''|}} |- {{Setting|'''Attach&nbsp;left&nbsp;endpoint'''|If checked, then the left endpoint of the rope is attached to its initial position and cannot move unless it is connected to a moving object.}} |- {{Setting|'''Attach&nbsp;right&nbsp;endpoint'''|If checked, then the right endpoint of the rope is attached to its initial position and cannot move unless it is connected to a moving object.}} |- {{Setting|'''Left&nbsp;attachment&nbsp;connector&nbsp;key'''|The connector key through which the left endpoint of the rope is connected to a moving object. If the left endpoint is connected to a rigid body, then the connector must connect to a direct subnode of the node to which the rigid body controller is assigned.}} |- {{Setting|'''Right&nbsp;attachment&nbsp;connector&nbsp;key'''|The connector key through which the right endpoint of the rope is connected to a moving object. If the right endpoint is connected to a rigid body, then the connector must connect to a direct subnode of the node to which the rigid body controller is assigned.}} |} == Script Functions == The rope controller defines the following functions that can be called from a [[Script Editor | script]] using the '''Call Controller Function''' method. {| {{Table}} {{Tablehead|Function|Description}} |- {{Tablerow|'''Break&nbsp;Rope&nbsp;Attachment'''|Breaks the left and/or right endpoint attachments of a rope geometry. * The '''Break left attachment''' setting specifies whether the left endpoint attachment should be broken. * The '''Break right attachment''' setting specifies whether the right endpoint attachment should be broken.}} |} == See Also == * [http://c4engine.com/docs/PhysicsMgr/RopeController.html <code>RopeController</code>] class * [[Cloth Controller]] * [[Physics]] [[Category:Physics]] [[Category:Controllers]] a48a1918d11c0450943036145a67f22bdb549bd2 Cloth Controller 0 112 114 2023-07-15T10:44:21Z Eric Lengyel 1 Created page with "__NOTOC__ The '''Cloth Controller''' is the type of controller assigned to a dynamic cloth geometry. The Cloth Controller is built into the core engine, and it is part of the Physics Manager. == Settings == The following settings are available for Cloth Controllers. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Deformable&nbsp;Body&nbsp;Flags'''|}} |- {{Setting|'''Ignore&nbsp;force&nbsp;fields'''|If checked, then force fields do not affect this..." wikitext text/x-wiki __NOTOC__ The '''Cloth Controller''' is the type of controller assigned to a dynamic cloth geometry. The Cloth Controller is built into the core engine, and it is part of the Physics Manager. == Settings == The following settings are available for Cloth Controllers. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Deformable&nbsp;Body&nbsp;Flags'''|}} |- {{Setting|'''Ignore&nbsp;force&nbsp;fields'''|If checked, then force fields do not affect this cloth geometry.}} |- {{HeadingSetting|'''Time&nbsp;Settings'''|}} |- {{Setting|'''Warm&nbsp;start&nbsp;time&nbsp;interval&nbsp;(s)'''|The length of time over which the cloth simulation is warmed up when a world is first loaded. This is not an actual length of time that you must wait, but it determines the number of internal simulation steps that are run as quickly as possible in order to give the cloth time to reach a steady state.}} |- {{Setting|'''Invisible&nbsp;time&nbsp;before&nbsp;sleeping&nbsp;(s)'''|The length of time that a cloth geometry must not be rendered before the controller automatically goes to sleep in order to save processing time. When a cloth controller automatically goes to sleep, it wakes up the next time the cloth geometry is rendered, except in cases when the controller has explicitly been put to sleep by the Sleep Controller script method or by the <code>Controller::Sleep()</code> function.}} |- {{HeadingSetting|'''Physical&nbsp;Properties'''|}} |- {{Setting|'''Cloth&nbsp;thickness&nbsp;(m)'''|The thickness of the cloth, in meters, given to the cloth when interacting with blockers. This setting does not affect the physical appearance of a cloth geometry, but allows some thickness to be specified to prevent visible penetration of other geometry where blockers are used.}} |- {{Setting|'''Particle&nbsp;mass&nbsp;(kg)'''|The mass of each simulated particle composing the cloth. For a cloth geometry, the number of simulated particles is (''w'' + 1) &times; (''h'' + 1), where ''w'' and ''h'' are the number of subdivisions specified in the ''x'' and ''y'' directions.}} |- {{Setting|'''Gravity&nbsp;multiplier'''|The factor by which the force of gravity is multiplied for this cloth geometry.}} |- {{Setting|'''Fluid&nbsp;drag&nbsp;multiplier'''|The factor by which fluid drag forces are multiplied for this cloth geometry.}} |- {{Setting|'''Wind&nbsp;drag&nbsp;multiplier'''|The factor by which wind drag forces are multiplied for this cloth geometry.}} |- {{Setting|'''Internal&nbsp;resistance'''|The amount of internal resistance to motion for this cloth geometry. This setting slows the velocities of the simulated particles.}} |- {{HeadingSetting|'''Spring&nbsp;Settings'''|}} |- {{Setting|'''Stretch&nbsp;spring&nbsp;coefficient'''|The spring stiffness coefficient for &ldquo;stretch&rdquo; springs, which connect adjacent particles in the ''x'' and ''y'' directions.}} |- {{Setting|'''Shear&nbsp;spring&nbsp;coefficient'''|The spring stiffness coefficient for &ldquo;shear&rdquo; springs, which connect adjacent particles diagonally.}} |- {{Setting|'''Bend&nbsp;spring&nbsp;coefficient'''|The spring stiffness coefficient for &ldquo;bend&rdquo; springs, which connect particles that are two positions apart in the ''x'' and ''y'' directions.}} |- {{HeadingSetting|'''Damper&nbsp;Settings'''|}} |- {{Setting|'''Stretch&nbsp;damper&nbsp;coefficient'''|The spring damping coefficient for &ldquo;stretch&rdquo; springs, which connect adjacent particles in the ''x'' and ''y'' directions.}} |- {{Setting|'''Shear&nbsp;damper&nbsp;coefficient'''|The spring damping coefficient for &ldquo;shear&rdquo; springs, which connect adjacent particles diagonally.}} |- {{Setting|'''Bend&nbsp;damper&nbsp;coefficient'''|The spring damping coefficient for &ldquo;bend&rdquo; springs, which connect particles that are two positions apart in the ''x'' and ''y'' directions.}} |- {{HeadingSetting|'''Attachment&nbsp;Settings'''|}} |- {{Setting|'''Attach&nbsp;lower-left&nbsp;corner'''|If checked, then the lower-left corner of the cloth is attached to its initial position and cannot move.}} |- {{Setting|'''Attach&nbsp;lower-right&nbsp;corner'''|If checked, then the lower-right corner of the cloth is attached to its initial position and cannot move.}} |- {{Setting|'''Attach&nbsp;upper-right&nbsp;corner'''|If checked, then the upper-right corner of the cloth is attached to its initial position and cannot move.}} |- {{Setting|'''Attach&nbsp;upper-left&nbsp;corner'''|If checked, then the upper-left corner of the cloth is attached to its initial position and cannot move.}} |- {{Setting|'''Attach&nbsp;bottom&nbsp;edge'''|If checked, then all of the particles along the bottom edge of the cloth are attached to their initial positions and cannot move.}} |- {{Setting|'''Attach&nbsp;right&nbsp;edge'''|If checked, then all of the particles along the right edge of the cloth are attached to their initial positions and cannot move.}} |- {{Setting|'''Attach&nbsp;top&nbsp;edge'''|If checked, then all of the particles along the top edge of the cloth are attached to their initial positions and cannot move.}} |- {{Setting|'''Attach&nbsp;left&nbsp;edge'''|If checked, then all of the particles along the left edge of the cloth are attached to their initial positions and cannot move.}} |} == See Also == * [http://c4engine.com/docs/PhysicsMgr/ClothController.html <code>ClothController</code>] class * [[Rope Controller]] * [[Physics]] [[Category:Physics]] [[Category:Controllers]] 4cfc241f4a612ebb947f61db264bfeca4933404d Category:Controllers 14 113 115 2023-07-15T10:44:41Z Eric Lengyel 1 Created blank page wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Category:Physics 14 114 116 2023-07-15T10:44:52Z Eric Lengyel 1 Created blank page wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Rigid Body Controller 0 115 117 2023-07-15T10:45:26Z Eric Lengyel 1 Created page with "__NOTOC__ The '''Rigid Body Controller''' is a type of controller that represents a rigid body in a physics simulation. The Rigid Body Controller is built into the core engine, and it's used for all solid objects that move under the control of the built-in physics system. == Settings == The following settings are available for Rigid Body Controllers. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Rigid&nbsp;Body&nbsp;Flags'''|}} |- {{Setting|'''..." wikitext text/x-wiki __NOTOC__ The '''Rigid Body Controller''' is a type of controller that represents a rigid body in a physics simulation. The Rigid Body Controller is built into the core engine, and it's used for all solid objects that move under the control of the built-in physics system. == Settings == The following settings are available for Rigid Body Controllers. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Rigid&nbsp;Body&nbsp;Flags'''|}} |- {{Setting|'''Initially&nbsp;asleep'''|If checked, then the rigid body is initially in the sleeping state. It will not be moved under it is explicitly awakened or another object collides with it.}} |- {{Setting|'''Ignore&nbsp;force&nbsp;fields'''|If checked, then force fields do not affect this rigid body.}} |- {{HeadingSetting|'''Physical&nbsp;Properties'''|}} |- {{Setting|'''Gravity&nbsp;multiplier'''|The factor by which the force of gravity is multiplied for this rigid body.}} |- {{Setting|'''Fluid&nbsp;drag&nbsp;multiplier'''|The factor by which fluid drag forces are multiplied for this rigid body.}} |- {{Setting|'''Wind&nbsp;drag&nbsp;multiplier'''|The factor by which wind drag forces are multiplied for this rigid body.}} |- {{Setting|'''Restitution&nbsp;coefficient'''|The fraction of momentum that is retained when this rigid body bounces during a collision.}} |- {{Setting|'''Friction&nbsp;coefficient'''|The coefficient used in friction force calculations. This value should usually be between 0.0 and 1.0.}} |- {{Setting|'''Spin&nbsp;friction&nbsp;multiplier'''|Determines how much friction is applied in the special case that the rigid body is spinning on a single point like a top. This value should be between 0.0 and 1.0, and it multiplies the ordinary friction coefficient.}} |- {{Setting|'''Rolling&nbsp;resistance'''|The internal force that is applied to counteract this rigid body's angular velocity. Good values for the rolling resistance usually lie between 0.0 and 0.1.}} |- {{HeadingSetting|'''Sleep&nbsp;Parameters'''|}} |- {{Setting|'''Sleep&nbsp;box&nbsp;multiplier'''|Multiplies the size of the sleep boxes used to determine when a rigid body should go to sleep. Larger values increase the tendency for a rigid body to sleep, and smaller values cause a rigid body to stay awake longer.}} |- {{Setting|'''Rotational&nbsp;multiplier'''|An additional multiplier for the rotational sleep boxes that influences how quickly a rotating object falls asleep.}} |- {{HeadingSetting|'''Network&nbsp;Settings'''|}} |- {{Setting|'''Snapshot&nbsp;period'''|The time between network snapshots for this rigid body. Larger values mean that the motion of the rigid body is predicted on client machines for a longer time before being corrected, but network traffic is also lowered.}} |} == See Also == * [http://c4engine.com/docs/PhysicsMgr/RigidBodyController.html <code>RigidBodyController</code>] class * [[Physics Controller]] * [[Physics]] [[Category:Physics]] [[Category:Controllers]] 49c40bf99efda8419288e38ebdcec7105f82eaeb Physics Controller 0 116 118 2023-07-15T10:45:50Z Eric Lengyel 1 Created page with "__NOTOC__ The '''Physics Controller''' is a type of controller that represents the global physics simulation. The Physics Controller is built into the core engine, and automatically assigned to the Physics Node when it is placed in the scene. A single Physics Node should be placed in any world that uses the built-in physics simulation by using the tool in the [[Physics Page]]. == Settings == The following settings are available for Physics Controllers. {| {{Table}} {{..." wikitext text/x-wiki __NOTOC__ The '''Physics Controller''' is a type of controller that represents the global physics simulation. The Physics Controller is built into the core engine, and automatically assigned to the Physics Node when it is placed in the scene. A single Physics Node should be placed in any world that uses the built-in physics simulation by using the tool in the [[Physics Page]]. == Settings == The following settings are available for Physics Controllers. {| {{Table}} {{Tablehead|Setting|Description}} |- {{Setting|'''Gravity&nbsp;acceleration&nbsp;(m/s<sup>2</sup>)'''|The normal acceleration of gravity for the whole world in meters per second squared. This can be changed on a per-object basis by using the '''Gravity multiplier''' setting of the [[Rigid Body Controller]].}} |} == Script Functions == The Physics Controller defines the following functions that can be called from a [[Script Editor | script]] using the '''Call Controller Function''' method. {| {{Table}} {{Tablehead|Function|Description}} |- {{Tablerow|'''Set Gravity'''|Sets the acceleration of gravity. * The '''Gravity acceleration (m/s<sup>2</sup>)''' setting specifies the new acceleration of gravity in meters per second squared.}} |} == See Also == * [http://c4engine.com/docs/PhysicsMgr/PhysicsController.html <code>PhysicsController</code>] class * [[Rigid Body Controller]] * [[Physics]] [[Category:Physics]] [[Category:Controllers]] b794ce2e04b5af3f30b8116980fce425893a8247 Animation Controller 0 117 119 2023-07-15T10:46:20Z Eric Lengyel 1 Created page with "__NOTOC__ The '''Animation Controller''' is a type of controller that can be used to play animations for a generic model. == Settings == The following settings are available for Animation Controllers. {| {{Table}} {{Tablehead|Setting|Description}} |- {{Setting|'''Initial animation name'''|The name of the animation resource that is initially applied to the model.}} |- {{Setting|'''Animation is initially playing'''|If checked, then the animation is initially playing whe..." wikitext text/x-wiki __NOTOC__ The '''Animation Controller''' is a type of controller that can be used to play animations for a generic model. == Settings == The following settings are available for Animation Controllers. {| {{Table}} {{Tablehead|Setting|Description}} |- {{Setting|'''Initial animation name'''|The name of the animation resource that is initially applied to the model.}} |- {{Setting|'''Animation is initially playing'''|If checked, then the animation is initially playing when the world is loaded. Otherwise, the animation is stopped.}} |- {{Setting|'''Animation plays in reverse'''|If checked, then the animation plays in reverse.}} |- {{Setting|'''Animation is looping'''|If checked, then the animation loops when it is played.}} |- {{Setting|'''Animation is oscillating'''|If checked, then the animation plays forward and then plays in reverse. If the animation is also looping, then this oscillation repeats.}} |} == Script Functions == The Animation Controller defines the following functions that can be called from a [[Script Editor | script]] using the '''Call Controller Function''' method. {| {{Table}} {{Tablehead|Function|Description}} |- {{Tablerow|'''Play Animation'''|Plays a new animation for the target model and completes immediately. * The '''Animation name''' setting specifies the name of the animation resource to play. * The '''Reverse''' setting specifies whether the animation plays in reverse. * The '''Loop''' setting specifies whether the animation loops. * The '''Oscillate''' setting specifies whether the animation oscillates.}} |- {{Tablerow|'''Stop Animation'''|Stops animation for the target model and completes immediately.}} |} == See Also == * [[Models Page]] [[Category:Controllers]] b3064b059b92541c7849fc2c2f3ad21fc529aa91 Distribution Controller 0 118 120 2023-07-15T10:46:51Z Eric Lengyel 1 Created page with "__NOTOC__ The '''Distribution Controller''' is a special type of controller that forwards the messages it receives to other controllers. This can be useful for performing the same action on multiple nodes in the world using only a single script method. If the target of a script method has a Distribution Controller attached to it, then it's as if the same script method were applied to all of the nodes to which the distribution controller forwards its messages. As an exam..." wikitext text/x-wiki __NOTOC__ The '''Distribution Controller''' is a special type of controller that forwards the messages it receives to other controllers. This can be useful for performing the same action on multiple nodes in the world using only a single script method. If the target of a script method has a Distribution Controller attached to it, then it's as if the same script method were applied to all of the nodes to which the distribution controller forwards its messages. As an example, suppose that you want to hide five different geometry nodes in a world. You could place a marker node somewhere, attach a Distribution Controller to it, and connect it to the five geometry nodes. The node to which a script is attached would be connected to the marker node with the Distribution Controller, and the script would contain a '''Hide Geometry''' method that targets the marker node. If the '''Distribute messages through connectors''' option is selected for the Distribution Controller, then '''Hide Geometry''' method would cause all five connected geometry nodes to be hidden. == Settings == The following settings are available for Distribution Controllers. The ''target node'' is the node to which the distribution controller is attached. If more than one of the following options is selected, then all of the selected options apply. {| {{Table}} {{Tablehead|Setting|Description}} |- {{Setting|'''Distribute messages to self'''|Specifies that messages should be processed by the Distribution Controller itself and thus applied to the target node.}} |- {{Setting|'''Distribute messages to subnodes'''|Specifies that messages should be forwarded to all immediate subnodes of the target node.}} |- {{Setting|'''Distribute messages through connectors'''|Specifies that messages should be forwarded to all nodes to which the target node is connected.}} |} == See Also == * [http://c4engine.com/docs/Controller/DistributionController.html <code>DistributionController</code>] class * [[Script Editor]] * [[Methods]] [[Category:Controllers]] [[Category:Scripts]] 855f5fd4c85882070264072183f3ce74f92e9541 Defining a Custom Controller 0 119 121 2023-07-15T10:48:22Z Eric Lengyel 1 Created page with "In the C4 Engine, a ''controller'' is attached to a node to give it some kind of dynamic behavior. A controller is represented by a subclass of the [http://c4engine.com/docs/Controller/Controller.html <code>Controller</code>] class and contains all of the information needed to move or change an object in some way. It is often the case that a controller is assigned to a node and configured in the World Editor under the Controller tab in the Node Info window. == Defining..." wikitext text/x-wiki In the C4 Engine, a ''controller'' is attached to a node to give it some kind of dynamic behavior. A controller is represented by a subclass of the [http://c4engine.com/docs/Controller/Controller.html <code>Controller</code>] class and contains all of the information needed to move or change an object in some way. It is often the case that a controller is assigned to a node and configured in the World Editor under the Controller tab in the Node Info window. == Defining a Controller Subclass == In this article, we will use the example of a controller called <code>TwistController</code> that simply twists a node around its ''z'' axis. Note that this particular functionality already exists as part of the more general built-in [[Spin Controller]], so the example here is for illustrative purposes only. A custom controller subclass needs to have a unique type identifier that is registered with the engine so that the [[World Editor]] knows about it. The type identifier is a 32-bit number normally represented by a four-character string as in the following code. <source lang="cpp"> enum { kControllerTwist = 'twst' }; </source> (Type identifiers consisting of only uppercase letters and numbers are reserved for use by the engine. Anything else is okay for an application to use.) Next, the controller subclass needs to be defined. We declare the <code>TwistController</code> class to be a subclass of the <code>Controller</code> class as follows. We include some data members, one of which holds the rate at which the target node should twist. Several member functions are included to handle serialization and user interface&mdash;these are discussed below. <source lang="cpp"> class TwistController : public Controller { private: float twistRate; // In radians per millisecond. float twistAngle; // The current angle, in radians. Transform4D originalTransform; // The target's original transform. TwistController(const TwistController& twistController); Controller *Replicate(void) const; public: TwistController(); TwistController(float rate); ~TwistController(); float GetTwistRate(void) const { return (twistRate); } void SetTwistRate(float rate) { twistRate = rate; } static bool ValidNode(const Node *node); // Serialization functions. void Pack(Packer& data, uint32 packFlags) const override; void Unpack(Unpacker& data, uint32 unpackFlags) override; // User interface functions. void BuildSettingList(List<Setting> *settingList) const override; void CommitSetting(const Setting *setting) override; void PreprocessController(void); // The function that moves the target node. void MoveController(void); }; </source> The constructor and destructor for this example would typically be implemented as follows. <source lang="cpp"> TwistController::TwistController() : Controller(kControllerTwist) { // Set a default value for the twist rate of one revolution per second. twistRate = Math::two_pi / 1000.0F; twistAngle = 0.0F; } TwistController::TwistController(float rate) : Controller(kControllerTwist) { twistRate = rate; twistAngle = 0.0F; } TwistController::~TwistController() { } </source> Notice that the controller's type <code>kControllerTwist</code> is passed to the base class's constructor. The default constructor only needs to set a default value if the controller will be exposed in the World Editor. Otherwise, the default constructor will only be called right before the controller is deserialized, thus filling in the data members. The copy constructor and the <code>Replicate()</code> function must be included for all controllers. For this example, the copy constructor would be implemented as follows. <source lang="cpp"> TwistController::TwistController(const TwistController& twistController) : Controller(twistController) { twistRate = twistController.twistRate; twistAngle = 0.0F; } </source> It's important to observe that the reference to the copied <code>TwistController</code> object is passed to the base class constructor this time instead of the controller's type identifier. The <code>Replicate()</code> function simply constructs a new instance of the controller using the copy constructor. This would usually be implemented as follows. <source lang="c++"> Controller *TwistController::Replicate(void) const { return (new TwistController(*this)); } </source> == Controller Registration == A custom controller type must be registered with the engine in order to be recognized by the World Editor. This is accomplished by creating a ControllerReg object. The controller registration contains information about the controller type and its name, and it's mere existence registers the controller type that it represents. A controller registration for the TwistController class would normally look like the following. <source lang="cpp"> // Define the controller registration. ControllerReg<TwistController> twistControllerReg; </source> The registration object is initialized with the following code. <source lang="cpp"> twistControllerReg(kControllerTwist, "Twist"); </source> The <code>ValidNode()</code> function declared in the <code>TwistController</code> class is used by the World Editor to determine what kind of node the controller was meant to be assigned to. If this function is not included in the class definition, then the controller can be assigned to any node. Otherwise, the <code>ValidNode()</code> function should return <code>true</code> when it's okay to assign the controller to the node passed to it, and <code>false</code> if it's not okay. As an example, if we only wanted <code>TwistController</code> objects to be assigned to geometry nodes, then we would implement the <code>ValidNode()</code> function as follows. <source lang="c++"> bool TwistController::ValidNode(const Node *node) { return (node->GetNodeType() == kNodeGeometry); } </source> Notice that the <code>ValidNode()</code> function is declared <code>static</code>. The World Editor calls this function automatically when it needs to know whether the controller can be used with a specific node. == Serialization == A custom controller must implement the <code>Pack()</code> and <code>Unpack()</code> functions so that its data can be written to a file and later restored. (These functions override the virtual functions in the [http://c4engine.com/docs/ResourceMgr/Packable.html <code>Packable</code>] class.) Each of these functions needs to first call its counterpart in the <code>Controller</code> base class. For the <code>TwistController</code> example, these functions would typically be implemented as follows. <source lang="cpp"> void TwistController::Pack(Packer& data, uint32 packFlags) const { Controller::Pack(data, packFlags); // Write the twist rate. data << twistRate; // Write the current angle. data << twistAngle; // Write the original transform. data << originalTransform; } void TwistController::Unpack(Unpacker& data, uint32 unpackFlags) { Controller::Unpack(data, unpackFlags); // Read the twist rate. data >> twistRate; // Read the current angle. data >> twistAngle; // Read the original transform. data >> originalTransform; } </source> == User Interface == The <code>Controller</code> class is a subclass of the [http://c4engine.com/docs/InterfaceMgr/Configurable.html <code>Configurable</code>] class, which means it can expose a user interface that appears in the [[World Editor]]. The <code>Controller</code> object is queried by the World Editor for its configurable settings when the user opens the Node Info window for a node with a controller attached to it. The <code>BuildSettingList()</code> function is called when the editor needs all of the configurable settings to be built, and the <code>CommitSetting()</code> function is called for each setting when the user confirms the new configuration. For the <code>TwistController</code> example, there is one setting representing the twist rate stored in the controller object. The user interface to change this value would be implemented as follows. <source lang="cpp"> void TwistController::BuildSettingList(List<Setting> *settingList) const { // There is one setting, and it's an editable text field. settingList->AppendListElement(new TextSetting('rate', "Twist rate", Text::FloatToString(twistRate * 1000.0F / Math::two_pi))); } void TwistController::CommitSetting(const Setting *setting) { // Are we setting the twist rate? if (setting->GetSettingIdentifier() == 'rate') { // Yes, grab the rate value from the setting. const char *text = static_cast<const TextSetting *>(setting)->GetText(); twistRate = Text::StringToFloat(text) * Math::two_pi * 0.001F; } } </source> The first parameter passed to the <code>TextSetting</code> constructor (<code>'rate'</code>) is just an identifier that the controller uses to keep track of which setting is which&mdash;it can be anything you want. The second parameter is the title of the setting that, in this case, will be displayed next to the editable text box. The third parameter is the value that will initially be shown to the user. == Moving the Target Node == The <code>PreprocessController()</code> function is called once when the controller's target node is inserted into a world. In this function, we record the original transformation matrix for the target node so that we have a reference frame to which rotations are later going to be applied. We also make sure that the <code>kGeometryDynamic</code> flag is set for any geometry nodes in the subtree rooted at the target node. This tells the engine not to cache certain types of information for the objects that we're going to be moving. The body of our <code>PreprocessController()</code> function is shown below. Note that the base class's <code>PreprocessController()</code> function should always be called. <source lang="cpp"> void TwistController::PreprocessController(void) { PreprocessController::Preprocess(); // Grab the original transform of the target node. const Node *target = GetTargetNode(); originalTransform = target->GetNodeTransform(); // Set the kGeometryDynamic flag for any geometry nodes. const Node *node = target; do { if (node->GetNodeType() == kNodeGeometry) { // Node is a geometry, so grab its object. GeometryObject *object = static_cast<const Geometry *>(node)->GetObject(); // Set the kGeometryDynamic flag. object->SetGeometryFlags(object->GetGeometryFlags() | kGeometryDynamic); } // Iterate through entire subtree. node = target->GetNextTreeNode(node); } while (node); } </source> The <code>MoveController()</code> function is called once per frame to let the controller move its target node. In the case of the <code>TwistController</code> class, we just want to update the twist angle and calculate a new transform for the target node. The body of our <code>MoveController()</code> function looks like the following. (We do not need to call the base class's <code>MoveController()</code> function.) <source lang="cpp"> void TwistController::MoveController(void) { Matrix3D rotator; // Calculate the new twist angle based on how much time has passed. float angle = twistAngle + twistRate * TheTimeMgr->GetFloatDeltaTime(); // Make sure it's in the [-pi, pi] range. if (angle > Math::pi) angle -= Math::two_pi; else if (angle < -Math::pi) angle += Math::two_pi; twistAngle = angle; // Now make a 3x3 rotation matrix. rotator.SetRotationAboutZ(angle); // We'll rotate about the object-space center of the target node's bounding box. Node *target = GetTargetNode(); Point3D objectCenter = target->GetInverseWorldTransform() * target->GetBoundingBox()->GetCenter(); // Make a 3x4 transform that rotates about the center point. Transform4D transform(rotator, objectCenter - rotator * objectCenter); // Apply the rotation transform to the original transform and // assign it to the node as its new transform. target->SetNodeTransform(originalTransform * transform); // Invalidate the target node so that it gets updated properly. target->InvalidateNode(); } </source> == See Also == * [http://c4engine.com/docs/Controller/Controller.html <code>Controller</code> class] * [http://c4engine.com/docs/Controller/ControllerReg.html <code>ControllerReg</code> class] [[Category:Controllers]] c8f7b8b8bc4c9daecbd4ecacb57e9bf807c78544 Defining a Custom Method 0 120 122 2023-07-15T10:49:38Z Eric Lengyel 1 Created page with "In the C4 Engine, a ''method'' refers to an individual action that can appear in a script. There are many types of methods built into the engine, and an application can define its own custom methods by implementing new subclasses of the [http://c4engine.com/docs/Controller/Method.html Method] class. == Defining a Method Subclass == In this article, we will use the example of a method called <code>ChangeLightColorMethod</code> that simply changes the color of a light so..." wikitext text/x-wiki In the C4 Engine, a ''method'' refers to an individual action that can appear in a script. There are many types of methods built into the engine, and an application can define its own custom methods by implementing new subclasses of the [http://c4engine.com/docs/Controller/Method.html Method] class. == Defining a Method Subclass == In this article, we will use the example of a method called <code>ChangeLightColorMethod</code> that simply changes the color of a light source. Note that this particular functionality already exists as part of the more general built-in method '''Change Settings''', so the example here is for illustrative purposes only. A custom method subclass needs to have a unique type identifier that is registered with the engine so that the [[Script Editor]] knows about it. The type identifier is a 32-bit number normally represented by a four-character string as in the following code. <source lang="c++"> enum { kMethodChangeLightColor = 'litc' }; </source> (Type identifiers consisting of only uppercase letters and numbers are reserved for use by the engine. Anything else is okay for an application to use.) Next, the method subclass needs to be defined. We declare the <code>ChangeLightColorMethod</code> class to be a subclass of the <code>Method</code> class as follows, and we include a single data member to hold the color value that will be assigned to a light source when the method executes. Several member functions are included to handle serialization and user interface&mdash;these are discussed below. <source lang="c++"> class ChangeLightColorMethod : public Method { private: ColorRGB lightColor; ChangeLightColorMethod(const ChangeLightColorMethod& changeLightColorMethod); Method *Replicate(void) const; public: ChangeLightColorMethod(); ChangeLightColorMethod(const ColorRGB& color); ~ChangeLightColorMethod(); const ColorRGB& GetLightColor(void) const { return (lightColor); } void SetLightColor(const ColorRGB& color) { lightColor = color; } // Serialization functions. void Pack(Packer& data, uint32 packFlags) const override; void Unpack(Unpacker& data, uint32 unpackFlags) override; // User interface functions. void BuildSettingList(List<Setting> *settingList) const override; void CommitSetting(const Setting *setting) override; // This function is called when the method is executed in a script. void ExecuteMethod(const ScriptState *state) override; }; </source> The constructor and destructor for this example would typically be implemented as follows. <source lang="c++"> ChangeLightColorMethod::ChangeLightColorMethod() : Method(kMethodChangeLightColor) { // Set a default value. lightColor.Set(1.0F, 1.0F, 1.0F); } ChangeLightColorMethod::ChangeLightColorMethod(const ColorRGB& color) : Method(kMethodChangeLightColor) { lightColor = color; } ChangeLightColorMethod::~ChangeLightColorMethod() { } </source> Notice that the method's type <code>kMethodChangeLightColor</code> is passed to the base class constructor. The copy constructor and the <code>Replicate()</code> function must be included for all methods. For this example, the copy constructor would be implemented as follows. <source lang="c++"> ChangeLightColorMethod::ChangeLightColorMethod(const ChangeLightColorMethod& changeLightColorMethod) : Method(changeLightColorMethod) { lightColor = changeLightColorMethod.lightColor; } </source> It's important to observe that the reference to the copied <code>ChangeLightColorMethod</code> object is passed to the base class constructor this time instead of the method's type identifier. The <code>Replicate()</code> function simply constructs a new instance of the method using the copy constructor. This should always be implemented as follows. <source lang="c++"> Method *ChangeLightColorMethod::Replicate(void) const { return (new ChangeLightColorMethod(*this)); } </source> == Method Registration == A custom method type must be registered with the engine in order to be recognized by the [[Script Editor]]. This is accomplished by creating a <code>MethodReg</code> object. The method registration contains information about the method type and its name, and it's mere existence registers the method type that it represents. A method registration for the <code>ChangeLightColorMethod</code> class would normally look like the following. <source lang="c++"> // Define the method registration. MethodReg<ChangeLightColorMethod> changeLightColorRegistration; </source> The registration object is initialized with the following code. <source lang="c++"> changeLightColorRegistration(kMethodChangeLightColor, "Change Light Color"); </source> There is an optional third parameter that can specify flags for the method, and these are described in the documentation for the [http://c4engine.com/docs/Controller/MethodReg.html MethodReg] class. == Serialization == A custom method must implement the <code>Pack()</code> and <code>Unpack()</code> functions so that its data can be written to a file and later restored. (These functions override the virtual functions in the [http://c4engine.com/docs/ResourceMgr/Packable.html <code>Packable</code>] class.) Each of these functions needs to first call its counterpart in the <code>Method</code> base class. For the <code>ChangeLightColorMethod</code> example, these functions would typically be implemented as follows. <source lang="c++"> void ChangeLightColorMethod::Pack(Packer& data, uint32 packFlags) const { Method::Pack(data, packFlags); // Write the ColorRGB object. data << lightColor; } void ChangeLightColorMethod::Unpack(Unpacker& data, uint32 unpackFlags) { Method::Unpack(data, unpackFlags); // Read the ColorRGB object. data >> lightColor; } </source> == User Interface == The <code>Method</code> class is a subclass of the [http://c4engine.com/docs/InterfaceMgr/Configurable.html <code>Configurable</code>] class, which means it can expose a user interface that appears in the [[Script Editor]]. The <code>Method</code> object is queried by the Script Editor for its configurable settings when the user double-clicks on the method to open its Method Info window. The <code>BuildSettingList()</code> function is called when the editor needs all of the configurable settings to be built, and the <code>CommitSetting()</code> function is called for each setting when the user confirms the new configuration. For the <code>ChangeLightColorMethod</code> example, there is one setting representing the light color stored in the method object. The user interface to change this color would be implemented as follows. <source lang="c++"> void ChangeLightColorMethod::BuildSettingList(List<Setting> *settingList) const { // There is one setting, and it's a color picker. settingList->AppendListElement(new ColorSetting('colr', lightColor, "Light color", "New Light Color")); } void ChangeLightColorMethod::CommitSetting(const Setting *setting) { // Are we setting the light color? if (setting->GetSettingIdentifier() == 'colr') { // Yes, grab the RGB color from the setting. lightColor = static_cast<const ColorSetting *>(setting)->GetColor().GetColorRGB(); } } </source> The first parameter passed to the <code>ColorSetting</code> constructor (<code>'colr'</code>) is just an identifier that the property uses to keep track of which setting is which&mdash;it can be anything you want. The second parameter is the color that will initially be shown to the user. The third parameter is the title of the setting that will be displayed next to the color box in the settings list. The last parameter is the title that will be used for the color picker dialog when the user clicks on the color box. == Method Execution == When a script is running and it's time to execute your custom method, the script controller calls the method's <code>ExecuteMethod()</code> function. A method can do anything it wants when it executes as long as it doesn't cause itself to be deleted. When a method finishes performing its actions, it needs to indicate that it has completed by calling the <code>HandleCompletion()</code> function of its [http://c4engine.com/docs/Utilities/Completable.html <code>Completable</code>] base class. A method may finish inside the call to its <code>ExecuteMethod()</code> function, or it may finish sometime later after more time-consuming operations have completed. The <code>ExecuteMethod()</code> function for the <code>ChangeLightColorMethod</code> class could be implemented as follows. <source lang="c++"> void ChangeLightColorMethod::Execute(const ScriptState *state) { // Get the target node for this method and // make sure it's actually a light source. Node *node = GetTargetNode(state); if ((node) && (node->GetNodeType() == kNodeLight)) { LightObject *object = static_cast<Light *>(node)->GetObject(); // Set the new light color. object->SetLightColor(lightColor); // Mark the object as modified. object->SetModifiedFlag(); } // Indicate that we are finished. HandleCompletion(); } </source> The call to the <code>GetTargetNode()</code> function retrieves the node that the user has selected as the target of the method in the [[Script Editor]]. It's possible that this target hasn't been selected or that the user linked it to a node that was not a light source, so the above code performs some checks before it carries out its task. Some custom methods do not operate on a target node, and these methods should specify the <code>kMethodNoTarget</code> flag in the method registration so that the user cannot select a target node in the Script Editor. The [http://c4engine.com/docs/WorldMgr/Object_SetModifiedFlag.html <code>SetModifiedFlag()</code>] function should be called whenever an object is modified so that the engine knows to write the object data when a game is saved. If this flag is not set, then the original object data would be reloaded when a saved game is resumed. == Method Output Values == A method may produce an output value that can be stored in a script variable. A method may also generate an independent boolean result that is used for conditional execution of subsequent methods in a script. A method can specify its output value by calling the [http://c4engine.com/docs/Controller/Method_SetOutputValue.html <code>SetOutputValue()</code>] function. When a method outputs a value, it should specify the <code>kMethodOutputValue</code> flag in its method registration so that the [[Script Editor]] allows the user to assign an output variable to the method. If a method calls the <code>SetOutputValue()</code> function, then the boolean result for the method is automatically set according to the output value. A method can set the boolean result without specifying an output value, or it can override the output value, by calling the [http://c4engine.com/docs/Controller/Method_SetMethodResult.html <code>SetMethodResult()</code>] function. == See Also == * [[Script Editor]] * [[Methods]] * [http://c4engine.com/docs/Controller/Method.html <code>Method</code> class] * [http://c4engine.com/docs/Controller/MethodReg.html <code>MethodReg</code> class] [[Category:Scripts]] 9944fba13944ba4341e14415214ce3dc5d0fd8a7 File:Pipeline.png 6 121 123 2023-07-15T10:51:36Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 The C4 Rendering Pipeline 0 122 124 2023-07-15T10:51:42Z Eric Lengyel 1 Created page with "[[File:Pipeline.png|right|frame|'''Figure 1.''' The major stages of the C4 Engine rendering pipeline.]] The C4 Engine executes a complex sequence of rendering operations during each frame of gameplay. This article gives a high-level overview of the various components of the C4 Engine rendering pipeline so that users of the engine, having some knowledge of its internal processes, can achieve more efficient results. The following sections describe the rendering stages exec..." wikitext text/x-wiki [[File:Pipeline.png|right|frame|'''Figure 1.''' The major stages of the C4 Engine rendering pipeline.]] The C4 Engine executes a complex sequence of rendering operations during each frame of gameplay. This article gives a high-level overview of the various components of the C4 Engine rendering pipeline so that users of the engine, having some knowledge of its internal processes, can achieve more efficient results. The following sections describe the rendering stages executed by the engine in the order that they occur. == Structure Pass == The engine first goes through the scene (using the portal system and cell graph) to determine what objects are visible to the current camera. Once these have been collected, the appropriate detail levels are determined, and the objects are rendered with a special shader to the ''structure buffer''. The structure buffer is a four-channel 16-bit floating-point buffer that holds a 32-bit per-pixel camera-space depth and two 16-bit per-pixel derivatives of this depth, giving a screen-space gradient. This information is used in later stages of the rendering pipeline that need it to perform specific calculations with it. If [[Motion Blur | motion blur]] is enabled, then an additional two-channel 8-bit integer ''velocity buffer'' is rendered at the same time. The velocity buffer holds the per-pixel screen-space velocity of each surface in the scene, and it is used in the postprocessing stage to apply the motion blur effect. == SSAO Generation == If screen-space ambient occlusion (SSAO) is enabled, then the engine renders a full-screen pass that calculates an approximate ambient occlusion at each pixel using the information in the structure buffer. The resulting ambient occlusion data is stored in a texture map that's used later to modify the intensity of the ambient lighting. == Cascaded Shadow Map == If an infinite light is visible to the camera, then a [[Cascaded Shadow Mapping | cascaded shadow map]] is rendered next. The results are stored in an array texture that is used to draw shadows in the unified lighting pass. == Unified Lighting Pass == The unified lighting pass renders either the combined contribution of the ambient light and the infinite light or just the ambient light if no infinite light (with unified lighting enabled) is visible to the camera. Most of the major shading for the entire scene takes place here. The ambient light takes SSAO and radiosity spaces into account, and the infinite light uses the previously-rendered cascaded shadow map to draw shadows. The infinite light typically affects everything in an outside environment, but there are situations in which part of the scene is rendered with unified lighting and part is rendered with only ambient lighting. (For example, if the camera is inside a building and looking outside through a door or window.) If a [[Skyboxes | skybox]] is visible, then it is the last thing rendered in the unified lighting pass. This maximizes efficient use of hierarchical z-buffering hardware. Effect visibility is determined during the unified lighting pass, but effects are not rendered until a later stage. == Additional Lighting Passes == If there are more light sources visible to the camera, then their contributions are rendered after the unified lighting pass. The engine uses a complicated algorithm to determine which lights in the scene affect regions that are visible to the camera. For each of these lights, the engine also figures out which objects in the scene may cast shadows into visible regions, and this usually includes objects that are not directly visible and thus never actually rendered. For each visible light, the engine first renders shadows for all of the possible shadow castors for that light. For a point light, this involves rendering a cube shadow map, and for a spot light, this involves rendering a 2D shadow map. (There can also be additional infinite lights that involve rendering cascaded shadow maps.) Then the engine renders all objects that are both visible and illuminated by the light, being sure to prevent light from reaching surfaces that are in shadow. An object has a different shader for each of the different types of light supported by the engine. == Effect Pass == Once the unified lighting pass and all additional lighting passes have been rendered, the special effects that were previously determined to be visible are rendered. There are a few different effect rendering stages. The first stage renders opaque effects, such as scorch mark decals, that are always applied to previously rendered opaque objects. In the second stage, transparent effects that need to be sorted, such as fire and smoke, are rendered from furthest to nearest. Finally, in the third stage, other transparent effects, such as certain particle systems that don't need to be sorted, are rendered. Some effects use the depth information in the structure buffer to modify their appearance. For example, particles are able to use the depth to soften themselves when they get close to solid geometry so that clipping artifacts are not visible. == Multisample Resolve == After everything in the scene has been rendered, the multisampled rendering buffer is resolved into a single-sampled buffer to apply antialiasing. == Postprocess Effects == The final pass rendered by the engine takes care of postprocess effects. These are applied to the entire screen and have a constant performance cost that does not depend on the number of visible objects. The postprocess effects rendered by the engine at this point in the rendering pipeline are [[Motion Blur | motion blur]], glow and bloom, distortion effects, and a final color transformation. == See Also == * [[Lights and Shadows]] * [[Cascaded Shadow Mapping]] * [[Motion Blur]] 1678b38e4004cf4232645a2e0d61b65085900e2f File:Editor models.png 6 123 125 2023-07-15T10:52:42Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor worlds.png 6 124 126 2023-07-15T10:52:55Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Models and Instanced Worlds 0 125 127 2023-07-15T10:53:01Z Eric Lengyel 1 Created page with "__NOTOC__ There are two file formats in which scene data can be saved for use in the C4 Engine: # A world file having the <code>.wld</code> extension. # A model file having the <code>.mdl</code> extension. Both of these types of resources can contain just about any kind of scene data, and they can both be loaded into a larger world as instances of the data they contain. This article describes the differences between models and instanced worlds and discusses when one ty..." wikitext text/x-wiki __NOTOC__ There are two file formats in which scene data can be saved for use in the C4 Engine: # A world file having the <code>.wld</code> extension. # A model file having the <code>.mdl</code> extension. Both of these types of resources can contain just about any kind of scene data, and they can both be loaded into a larger world as instances of the data they contain. This article describes the differences between models and instanced worlds and discusses when one type should be used instead of the other. == Models == [[File:Editor_models.png|right|frame|'''Figure 1.''' The [[Models Page]] in the [[World Editor]] with a list of model resources registered by the demo game.]] A ''model'' is generally used for entities that exhibit complex behavior or are transient elements of the main scene. For example, things like characters, vehicles, weapons, ammo, and power-ups would usually be stored in model resources and placed in the scene as model nodes because they often have custom controllers attached to them, and they typically do not exist for the entire time that a game world is being played. There are two cases in which the use of models nodes is required: # The model needs to be animated with transform data stored in an animation resource having the <code>.anm</code> extension. # The model contains one or more skinned geometry meshes whose vertex positions are determined by the positions of bones in the model. The model node contains special code to handle these features. They are not available for instanced worlds. === Registration === Custom model types can be registered with the engine using the [http://c4engine.com/docs/WorldMgr/ModelRegistration.html <code>ModelRegistration</code>] class. The set of registered model types is displayed in the [[Models Page]] inside the [[World Editor]]. The advantage of model registration is that a specific controller type and set of property types can optionally be specified by the registration, and these cause a controller and set of properties to automatically be attached to each new instance of a particular model. This functionality is not available with instanced worlds. === World Editor === In the [[World Editor]], models are placed in the scene by using the tools in the [[Models Page]], shown in Figure 1. There is a tool for placing generic model nodes and a list of specific models that are registered by the currently loaded game module. The actual model resource to be loaded by a generic model node is specified in the model node's settings. For all of the registered models in the list, the registration tells the engine what model resource should be loaded and tells the editor what controller and properties to assign to the model node by default. Note that model nodes are displayed in the World Editor without the contents of the model resources they represent unless the Model Toggle button at the top of the editor window is selected. == Instanced Worlds == [[File:Editor_worlds.png|right|frame|'''Figure 2.''' The [[Worlds Page]] in the [[World Editor]] with a list of instanced worlds used by a particular world in the demo game.]] An ''instanced world'' is generally used for objects that are static elements of the scene or will exhibit only rigid body behavior under the control of the physics system. For example, things like trees, boulders, and buildings would usually be stored in world resources and placed in the scene as instance nodes because the don't move around, and they typically exist for the entire time that a game world is being played. Additionally, things like crates, barrels, and tires that can be moved around as rigid bodies but don't have any AI would be stored in world resources as well and placed in the scene as instance nodes just as static objects are. Instanced worlds can be nested to a depth of three levels. That is, instanced worlds can contain other instanced worlds, and they will be recursively loaded by the engine. Models cannot be nested. === World Editor === In the [[World Editor]], instanced worlds are placed in the scene by using the tools in the [[Worlds Page]], shown in Figure 2. There is a tool for placing new types of instance nodes and a list of the specific world resources that have already been placed in the scene. After a new instance node is placed in the scene, the world resource that it represents is specified in its node settings. Once the world has been set, it is added to the list of existing worlds. When a world is selected from that list, each click in the scene places a new instance of that world. Multiple worlds can be selected from the list at once (using the Shift and Ctrl keys) to cause one of those worlds to be selected at random each time a new instance is placed in the scene. Instanced worlds can have modifiers attached to them that alter their contents in some way when that are brought into the main scene. Modifiers are specified in the node settings for the instanced world. See the Modifiers article for more information. Note that instance nodes are displayed in the World Editor without the contents of the world resources they represent unless the Instanced World Toggle button at the top of the editor window is selected. == See Also == * [[Models Page]] * [[Worlds Page]] * [[Placement Page]] * [[Modifiers]] * [http://c4engine.com/docs/WorldMgr/ModelRegistration.html <code>ModelRegistration</code>] class 8bd99591273a4b8b9ae5a33cff4104691254479a File:Cascades.png 6 126 128 2023-07-15T10:54:06Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Cascaded Shadow Mapping 0 127 129 2023-07-15T10:54:10Z Eric Lengyel 1 Created page with "__NOTOC__ Cascaded shadow mapping is the method used by the C4 Engine to cast real-time dynamic shadows over very large areas for an infinite light source. This article describes the settings that control the sizes of the cascades and the transition areas between them, which affect the resolution of the shadows and the smoothness involved in changing from one cascade to another. == Shadow Settings == The infinite light generates up to four separate shadows maps during..." wikitext text/x-wiki __NOTOC__ Cascaded shadow mapping is the method used by the C4 Engine to cast real-time dynamic shadows over very large areas for an infinite light source. This article describes the settings that control the sizes of the cascades and the transition areas between them, which affect the resolution of the shadows and the smoothness involved in changing from one cascade to another. == Shadow Settings == The infinite light generates up to four separate shadows maps during every frame in which it is visible. These four shadow maps are rendered at different resolutions for four ''cascades'' of space corresponding to increasing distance ranges from the camera position. This concept is illustrated in the following diagram, where the camera is located at the position '''c''' and points to the right. [[Image:Cascades.png]] The sizes of the cascades are specified by four maximum distance settings in the Node Info window for the infinite light. As shown in the figure, these four distances determine the far planes for the four shadow cascades. Shadow maps for cascades closer to the camera are rendered at higher resolutions, and the distance between adjacent lower numbered cascades is typically lower than the distance between adjacent higher numbered cascades. If smaller distances are used, then the shadows are rendered at higher resolution, but the coverage of the shadowing is reduced as well. The four cascades overlap by a little bit so that a smooth transition from one resolution to the next can be rendered for objects that straddle a cascade boundary. The three transition lengths specify how much distance each cascade extends into the one preceding it. A short distance means a quick transition, and longer distances mean more gradual transitions. The transition length can be any distance smaller than the higher-resolution cascade's overall size, but it typically covers only a fraction of the whole cascade. == Shadow Casting and Receiving == Each cascade has its own shadow map. Because cascades overlap, shadow castors may contribute to more than one of these shadow maps, and in fact could contribute to all of the cascades. An object must be rendered into the shadow map ''n'' times if it crosses into ''n'' cascades, so this should be considered when designing your worlds. An object can also receive shadows in all four shadow cascades. Which shadow map to use is determined on a per-pixel basis in the shader, so the highest-resolution shadow map covering an object is always used wherever possible. In the transition area between cascades, samples from both cascades' shadow maps are blended together in order to produce a smooth transition from one resolution to the next. The number of cascades into which a shadow-receiving object crosses does not affect rendering performance. Whether an object falls completely in one cascade or extends through all four cascades, the rendering speed is the same. == See Also == * [[Lights and Shadows]] == Further Reading == * [http://foundationsofgameenginedev.com/ Lengyel, Eric. ''Foundations of Game Engine Development, Volume 2: Rendering'', Terathon Software, 2019. Section 8.3.3.] 1ab4fcec840b1b86362d933244e5a8bdb057e3b6 File:Motionblur.jpg 6 128 130 2023-07-15T10:55:22Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Motion Blur 0 129 131 2023-07-15T10:55:27Z Eric Lengyel 1 Created page with "[[File:Motionblur.jpg|right|frame|'''Figure 1.''' Motion blur is visible due to the movement of the camera and the falling debris.]] The C4 Engine is capable of rendering full-scene motion blur as a post-processing effect. Motion blur in C4 is based on the concept of a velocity buffer, and it employs a sophisticated algorithm that uses information in both the velocity buffer and the structure buffer to apply the correct blur after the entire scene has been rendered. The..." wikitext text/x-wiki [[File:Motionblur.jpg|right|frame|'''Figure 1.''' Motion blur is visible due to the movement of the camera and the falling debris.]] The C4 Engine is capable of rendering full-scene motion blur as a post-processing effect. Motion blur in C4 is based on the concept of a velocity buffer, and it employs a sophisticated algorithm that uses information in both the velocity buffer and the structure buffer to apply the correct blur after the entire scene has been rendered. The screen-space velocity of a single pixel depends on several factors, including the motion of the geometry occupying that pixel, the motion of the camera, and possibly the motion of different vertices within the geometry (for example, skinned characters and dynamic cloth have moving vertices). The engine takes all of these into account and generates an accurate velocity for all objects in the scene. In Figure 1 to the right, the ground is blurred because the player is moving backward, and the crumbling debris is blurred because is falling to the ground and rolling. == Controlling Motion Blur == In the demo game that ships with C4, motion blur can be enabled or disabled by the user in the Graphics Settings dialog. This works by setting the value of the <code>$postMotionBlur</code> system variable to either 0 or 1. Motion blur can be enabled or disabled on a per-geometry basis in the [[World Editor]] by selecting a geometry and opening the Node Info dialog. There is a check box under the Geometry tab called "Apply motion blur", which is enabled by default. This check box corresponds to the <code>kGeometryMotionBlurInhibit</code> flag that can be set for a <code>GeometryObject</code> using the <code>[http://c4engine.com/docs/WorldMgr/GeometryObject_SetGeometryFlags.html GeometryObject::SetGeometryFlags()]</code> function. It is sometimes necessary to explicitly tell the engine that an object has stopped moving so that motion blur for that object can be reset. (A stopped object is not normally being invalidated in the usual way, so the engine has no way of knowing that it needs attention.) The <code>[http://c4engine.com/docs/WorldMgr/Node_StopMotion.html Node::StopMotion()]</code> function can be called to update the internal transforms so that an object is correctly recognized as completely stopped. == Further Reading == * [http://foundationsofgameenginedev.com/ Lengyel, Eric. ''Foundations of Game Engine Development, Volume 2: Rendering'', Terathon Software, 2019. Section 10.6.] 6f2f391e4822257b9c8c3fc9fc6c462146d7d86d File:Editor atmosphere.png 6 130 132 2023-07-15T10:56:45Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Constantfog.jpg 6 131 133 2023-07-15T10:56:54Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Linearfog.jpg 6 132 134 2023-07-15T10:57:03Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Fog Spaces 0 133 135 2023-07-15T10:57:13Z Eric Lengyel 1 Created page with "In the C4 Engine, a '''fog space''' is a node that causes fog to be rendered in a scene. It's actually a half-space because all space is divided in half by a single boundary plane, and fog is rendered on one side of the plane. == Creating a Fog Space == [[File:Editor_atmosphere.png|right]] A fog space is placed in a world using the Fog Space tool in the [[Atmosphere Page]] (shown to the right) in the [[World Editor]] under the Object tab. This tool draws a rectangular..." wikitext text/x-wiki In the C4 Engine, a '''fog space''' is a node that causes fog to be rendered in a scene. It's actually a half-space because all space is divided in half by a single boundary plane, and fog is rendered on one side of the plane. == Creating a Fog Space == [[File:Editor_atmosphere.png|right]] A fog space is placed in a world using the Fog Space tool in the [[Atmosphere Page]] (shown to the right) in the [[World Editor]] under the Object tab. This tool draws a rectangular region that represents the top boundary of a fog volume. Fog is rendered everywhere beneath the entire plane containing this rectangle in the zone to which the fog space belongs. Fog is not rendered above the plane, but the plane can always be raised above the whole scene if the desired effect is to fog everything. When the camera is above the fog plane, the rectangular plate representing the fog space must be visible in order for fog to be rendered, so it should be drawn large enough to cover the entire area that should be affected by fog. When the camera is below the fog plane in a zone affected by the fog space, fog is always rendered. The boundary plane of a fog space does not have to be horizontal and can placed in any orientation. An example use of a vertical fog plane is one that coincides with a doorway leading into a fogged area from an unfogged area. == Density Functions == [[File:Constantfog.jpg|right|frame|'''Figure 1.''' Fog with a constant density function.]] [[File:Linearfog.jpg|right|frame|'''Figure 2.''' Fog with a linear density function.]] In the Node Info dialog for a fog space, a fog color and density function can be selected. A fog space can use a constant fog density or a linear fog density. The difference is shown in the images to the right. When constant density is used, the density of the fog is the same everywhere beneath the boundary plane. When linear density is used, the density of the fog is zero at the boundary plane and increases linearly with distance beneath the plane. Typical density values for both modes are usually in the range of 0.001 to 0.1, where higher densities correspond to thicker fog. == Fog Space Settings == A fog space node can be configured under the Fog tab in the Node Info window. The specific settings are described in the following table. {| {{Table}} {{Tablehead|Setting|Description}} |- {{Tablerow|'''Fog&nbsp;color'''|The color of the fog space. When the amount of fog is calculated at each pixel, the fraction of light that does not make it through the fog is replaced by this color.}} |- {{Tablerow|'''Fog&nbsp;density'''|The constant density of the fog, or the rate at which the linear density increases. This is usually a small value less than 1.0.}} |- {{Tablerow|'''Density&nbsp;function'''|Selects whether the fog uses a constant density function or a linear density function.}} |- {{Tablerow|'''Apply&nbsp;distance&nbsp;occlusion'''|An optimization for thick fog that culls objects that are fully fogged based on their distance from the camera in the direction parallel to the fog plane. This should be enabled only if the fog ever becomes thick enough in the scene so that objects can't be seen beyond some horizontal distance.}} |- {{Tablerow|'''Apply&nbsp;depth&nbsp;occlusion'''|An optimization for thick fog that culls objects that are fully fogged based on their distance from the camera in the direction perpendicular to the fog plane. This should be enabled only if the fog ever becomes thick enough in the scene so that objects can't be seen beyond some vertical distance.}} |- {{Tablerow|'''Occlusion&nbsp;fog&nbsp;intensity'''|If either distance occlusion or depth occlusion is enabled, this value specifies the fog intensity at which objects are considered invisible. Higher values correspond to thicker fog being required to obscure an object. For bright fog colors, this value can usually be lower because the human eye cannot distinguish among bright colors as well as dark colors.}} |} == Using a Fog Space in Multiple Zones == A single fog space may be used to apply fog in multiple zones. A fog space automatically applies to the zone containing it in the transform hierarchy. Each zone node has a built-in [[Connectors | connector]] labeled <code>%Fog</code> that can be connected to a fog space in another zone. Every zone connected to a particular fog space is affected by the fog as long as the camera can see the fog plane or is inside the fog itself. It is okay for a fog space to extend beyond the boundary of its containing zone. Only one fog space should be visible at once for each perspective (primary, reflection, and refraction). If more than one fog space can be seen by the camera in a single perspective, then any one of them could be chosen to be applied to the scene, and this could change with the camera position. == See Also == * [http://c4engine.com/docs/WorldMgr/FogSpace.html <code>FogSpace</code>] class d0157a9fb1d6478594b84f09b7329b97259c5ade File:NewWorld1.png 6 134 136 2023-07-15T10:59:28Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:NewWorld2.png 6 135 137 2023-07-15T10:59:39Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:NewWorld3.png 6 136 138 2023-07-15T10:59:55Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:NewWorld4.png 6 137 139 2023-07-15T11:00:09Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:NewWorld5.png 6 138 140 2023-07-15T11:00:21Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:NewWorld6.png 6 139 141 2023-07-15T11:00:33Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:NewWorld7.png 6 140 142 2023-07-15T11:00:44Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:NewWorld8.png 6 141 143 2023-07-15T11:00:57Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:NewWorld9.png 6 142 144 2023-07-15T11:01:08Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:NewWorld10.png 6 143 145 2023-07-15T11:01:19Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:NewWorld11.png 6 144 146 2023-07-15T11:01:32Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:NewWorld12.png 6 145 147 2023-07-15T11:01:42Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:NewWorld13.png 6 146 148 2023-07-15T11:01:56Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:NewWorld14.png 6 147 149 2023-07-15T11:02:08Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:NewWorld15.png 6 148 150 2023-07-15T11:02:19Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 New World Tutorial 0 149 151 2023-07-15T11:02:24Z Eric Lengyel 1 Created page with "This tutorial teaches you how to create a new world from scratch in the C4 Engine and add all of the essential pieces for a typical game level. To enlarge any of the screenshots below, click on the thumbnail icon below the image. == Step A: Open the World Editor == To open the [[World Editor]] with a new empty world, select '''New World''' from the [[C4 Menu]] or type Ctrl-N when any user interface window is open. If you're running the demo game, you may want to hit E..." wikitext text/x-wiki This tutorial teaches you how to create a new world from scratch in the C4 Engine and add all of the essential pieces for a typical game level. To enlarge any of the screenshots below, click on the thumbnail icon below the image. == Step A: Open the World Editor == To open the [[World Editor]] with a new empty world, select '''New World''' from the [[C4 Menu]] or type Ctrl-N when any user interface window is open. If you're running the demo game, you may want to hit Escape after starting the engine to clear the main menu first. (Otherwise, it will continue rendering behind the World Editor.) If no user interface windows are open, you can always hit the tilde key to bring up the [[Command Console]]. When a new world editor window is opened, there is an empty scene containing nothing except the infinite zone, as shown in Figure 1. Every world has an infinite zone that directly or indirectly contains all of the other nodes that will ever exist in the world, and it cannot be deleted. [[File:NewWorld1.png|thumb|center|960px|'''Figure 1.''' A new world looks like this in the [[World Editor]].]] == Step B: Draw a Ground Plane == On the left side of the editor window, there is a column of ''tool pages''. All of the tools used for creating and modifying nodes in the world are found here, and they are divided into five groups under the tabs at the top of the column. Right now, we are going to use a tool from the [[Geometries Page]] at the top of the column under the '''Object''' tab. Click on the '''Plate Geometry''' tool in the upper-left corner of the '''Geometries Page'''. (The name of each tool will show up if you hover over it for a second.) This will change the current tool to one that creates new plate geometry nodes. In the '''Top''' viewport, click, drag out a rectangular shape, and then release the mouse button to add a new plate geometry to the world. (It doesn't matter exactly where you click or how large the rectangle is because we're going to update it later to make sure everyone who follows this tutorial gets the same results.) Your editor window should now look like the one shown in Figure 2. [[File:NewWorld2.png|thumb|center|960px|'''Figure 2.''' A new plate geometry has been added to the world.]] == Step C: Save the World == Before we continue, this would be a good time to save the world so we don't have to worry about it later when we want to play it. To save the world, type Ctrl-S. Since it hasn't been saved before, this will cause a dialog to appear where you can specify the name for your new world. After this first time, typing Ctrl-S will simply save to the file that has already been established. == Step D: Change the Default Material == The default material in a new world is simply a plain white color. Since it was the only material available, it has been applied to the new plate geometry that we created. We can change it by opening the [[Material Editor]] and assigning some texture maps. Click on the '''Material''' tab at the top of the column of tool pages. The [[Material Page]] will now be shown at the top of the column, and the only material in the list will be selected. Double-click on it to open the Material Editor, which is shown in Figure 3. [[File:NewWorld3.png|thumb|center|960px|'''Figure 3.''' The [[Material Editor]] has been opened for the default material.]] In the setting named '''Texture map (primary)''', click on the button with three dots inside on the right side of the window. This opens a dialog that lets you select a texture map. Navigate to the <code>Data/The31st/terrain</code> directory, and select <code>Grass3.tex</code>. This applies a diffuse texture map to the material. In the setting named '''Normal map (primary)''', use the same procedure to select <code>Grass3-nrml.tex</code>. This applies the normal map corresponding to the grass texture to the material. Of course, you can choose a different pair of texture maps if you'd like, as long as the diffuse and normal maps are matched to each other. Now click in the '''Material name''' box in the lower-left corner of the Material Editor and enter a name such as "Ground". Save the material by typing Ctrl-S, and you will see the modified material applied in the World Editor, both in the Material Page and in the perspective viewport, as shown in Figure 4. Close the Material Editor by clicking the X in the upper-right corner of the window or by typing Ctrl-W. [[File:NewWorld4.png|thumb|center|960px|'''Figure 4.''' The modified material has been saved and now appears in the World Editor.]] == Step E: Resize the Plate Geometry == So that everyone following this tutorial gets the same size ground plane, we will manually change the position and size of the plate geometry. Click on the '''Editor''' tab at the top of the column of tool pages, and find the [[Transform Page]]. If the plate geometry created earlier isn't still selected, then switch to the '''Select Tool''' (by using the shortcut key '''1''') and click on the plate in the top, scene graph, or perspective viewport. With the plate geometry selected, its position and size will appear in the Transform Page. Under the '''Position''' heading, set both the '''X''' and '''Y''' coordinates to &minus;20. Under the '''Size''' heading, set both the '''X''' and '''Y''' sizes to 40. This will change the plate geometry to a 40&times;40 square centered on the origin. Use the mouse wheel to zoom out in the '''Top''' viewport until the whole plate is visible. In the '''Perspective''' viewport, hold in the right mouse button and press the S key to move the camera backward until more of the plate is visible. (The camera can be moved around the perspective viewport in this manner by using standard first-person shooter controls.) The editor should now look like the screenshot in Figure 5. [[File:NewWorld5.png|thumb|center|960px|'''Figure 5.''' The plate geometry has been resized, and the camera has been moved outward to make it visible.]] == Step F: Add a Clear Color == By default, the engine does not take any action to reinitialize the frame buffer when one frame is done rendering and a new frame is begun. This is fine for indoor scenes because you can be sure that the whole screen will be covered by walls, the floor, the ceiling, etc. But for outdoor scenes, it would mean that the previous contents of frame buffer remain, and you see smearing from one frame to the next. There are two ways to make sure that everything is overdrawn for every frame, using a clear color and using a skybox. We will assign a clear color to the world now and add a skybox later. The clear color applies to the whole world, so it is a property associated with the infinite zone. To set the clear color, double-click on the '''Infinite Zone''' node in the '''Scene Graph''' viewport to open the Node Info window. (You can also select the node anywhere and type Ctrl-I.) Then click on the '''Properties''' tab in the Node Info window. A list of properties available for the currently selected node is displayed, and one of those properties is named '''Clear Color'''. Select the '''Clear Color''' property and click the '''Assign''' button. (You can also double-click on the property to assign it.) Under the '''Property Settings''' for the newly assigned '''Clear Color''' property, click on the black box for the '''Clear color''' setting. This opens a color picker dialog, as shown in Figure 6. You can choose whatever clear color you want, but we suggest using red, green, and blue values of 106, 129, and 135 because they will match the skybox that we're going to add to the world later. Once the color has been set, click OK for the color picker, click OK for the Node Info window. Your clear color will now appear in the background of the '''Perspective''' viewport. [[File:NewWorld6.png|thumb|center|960px|'''Figure 6.''' A clear color is being assigned to the world.]] == Step G: Expand the Infinite Zone == Because we selected the '''Infinite Zone''' in the previous step, this initially-hidden node has become visible. The infinite zone is supposed to contain everything in a world, but it starts out as a 1&times;1&times;1 cube that we can now see as a box with a green striped outline. For best performance, we need to resize this zone so that it's larger than everything else. Select the '''Resize Tool''' at the top of the World Editor window or use the shortcut key '''4'''. Little white handles will appear on the zone's boundary, and these can be dragged to change the size of the zone. Click on the lower-left and upper-right handles in the '''Top''' viewport and drag them outward until the zone is larger than the plate geometry with some extra padding. In the '''Front''' viewport, drag the top and bottom handles in the center of the box and drag them so that the zone has some height and depth. Your world should now look like the screenshot in Figure 7. Once the zone is resized, type Ctrl-H to hide and unselect the infinite zone. [[File:NewWorld7.png|thumb|center|960px|'''Figure 7.''' The infinite zone has been resized to contain the whole world.]] == Step H: Play the World and Return to the Editor == At this point, we've done enough that we can play the world in the engine without seeing a smeared background. The World Editor includes a mechanism for playing the current world and then returning to it in the editor, and it's good to get used to it as early as possible. Type Ctrl-P to play the world in the engine. This automatically saves the world first, so there's no need to type Ctrl-S first. The World Editor is closed, and the world you were editing is played in the exact same manner that it would be played in the final game. When you play this world, you will see the ground plane that we created above and the clear color that we established. The demo game contains code for a spectator camera that can be flown around using the W, S, A, and D keys. Moving the mouse changes the direction in which the camera moves. When you're ready to return to the editor, hit the tilde key to open the [[Command Console]] and type Ctrl-Shift-P. This causes the current world to be unloaded and the world most recently played from the World Editor to be re-opened. == Step I: Add a Physics Node and Spawn Location == It's possible to walk a character around in this world (using the demo game) after a couple more nodes are added. First, in order for any rigid body physics to be applied, a '''Physics Node''' needs to be created. The existence of this node tells the engine to use the built-in physics system, and it doesn't matter where we put it, as long as it's there. Switch to the '''Object''' tab of tool pages if it's not already selected, and use the mouse wheel to scroll down to the bottom where you will find the [[Physics Page]]. Select the '''Physics Node''' tool and click in the '''Top''' viewport to create a new physics node. It can go anywhere, but we choose to place it outside the ground plane so it's easy to find and doesn't get in the way of anything else. The editor window should now look like Figure 8. [[File:NewWorld8.png|thumb|center|960px|'''Figure 8.''' A physics node has been added to the world.]] Second, we need to tell the demo game where to spawn the player character. We do this by placing one or more '''Spawn''' locators in the world. (This is a custom type of locator marker that is defined by the demo game.) Scroll the tool pages up until you find the [[Markers Page]], and select the '''Spawn''' locator from the list. In the '''Top''' viewport, click near the center of the plate geometry that serves as the ground plane. The editor window should now look like Figure 9. [[File:NewWorld9.png|thumb|center|960px|'''Figure 9.''' A spawn locator has been added to the center of the ground plane.]] Type Ctrl-P to play the world. You can now use first-person controls to move the player around on the ground plane. When you're finished, hit tilde and type Ctrl-Shift-P to return to the editor. == Step J: Add a Substance and Physics Space == There are two things you may have noticed when walking around the world. First, there were no footstep sounds, and second, if you walk off the edge of the ground plane, you fall forever. We'll address both of these in this step. Footstep sounds are enabled by assigning a substance to the ground material. Go back to the Material Page and double-click on the ground material. In the Material Editor, select the '''Flags''' tab, and find the '''Substance''' setting at the bottom of the list. The available types of substances are defined by the demo game. Select '''Dirt''', and the Material editor should look like the screenshot in Figure 10. Type Ctrl-S to save the material, and type Ctrl-W to close the Material Editor. Because the material now has a substance assigned to it, the demo game knows what sounds to play for footsteps. You can hear different sounds by selecting another substance such as wood or stone. [[File:NewWorld10.png|thumb|center|960px|'''Figure 10.''' The substance for the ground material has been changed to '''Dirt'''.]] The player can be stopped from falling forever by using a special volume called a ''physics space''. A world may contain a single physics space that defines the absolute boundary of the entire physics simulation. Every world should have a physics space to prevent objects from unintentionally leaving the world and flying through the air forever. Select the '''Physics Space''' tool from the Physics Page, and drag out a box in the '''Top''' viewport that extends well beyond the edges of the ground plane. In the '''Front''' viewport, use the '''Resize Tool''' to move the bottom side of the physics space downward a little bit so it's not at the same vertical level as the ground. The editor should now look like Figure 11. [[File:NewWorld11.png|thumb|center|960px|'''Figure 11.''' A physics space has been added to the world.]] Before the physics space has any effect, the physics node that we created earlier needs to be [[Connectors|connected]] to it. Double-click on the '''Physics Node''' in the '''Scene Graph''' viewport to open its Node Info window, and select the '''Connectors''' tab. The list of '''Available Built-in Connectors''' contains a single item named <code>%Physics</code>. Double-click on this connector to assign it to the physics node. The Node Info window should now look like Figure 12. Click OK. [[File:NewWorld12.png|thumb|center|960px|'''Figure 12.''' The built-in <code>%Physics</code> connector has been assigned to the physics node.]] Select the '''Connect Tool''' at the top of the World Editor window or use the shortcut key '''5'''. The <code>%Physics</code> connector should now appear as an attachment to the physics node. (If the physics node accidentally became unselected, then just click on it in the '''Scene Graph''' viewport.) Click on the <code>%Physics</code> connector to select it, and then click on the physics space in any viewport. With the <code>%Physics</code> connector and physics space both selected, type Ctrl-L to link them together. This is the shortcut for the '''Connect Node''' command in the '''Node''' menu. The editor should now look like Figure 13. To stop it from obscuring your view, you may want to type Ctrl-H to hide the physics space at this point. [[File:NewWorld13.png|thumb|center|960px|'''Figure 13.''' The physics node has been connected to the physics space through the built-in <code>%Physics</code> connector.]] Type Ctrl-P to play the world. As the player character walks around, you can now hear footsteps. If you walk off the edge of the ground plane, then the player dies as soon as the character's position leaves the physics space. A game can take whatever action it wants when a rigid body leaves the physics space. The engine calls the <code>[http://c4engine.com/docs/PhysicsMgr/RigidBodyController_HandlePhysicsSpaceExit.html RigidBodyController::HandlePhysicsSpaceExit()]</code> function when this happens, and custom code can be implemented in a subclass of the <code>RigidBodyController</code> class. By default, any rigid body is immediately deleted when it leaves the physics space. == Step K: Add a Skybox == Up until this point, the sky in our world has been nothing but the solid clear color that we specified earlier. Now, we're going to add a skybox, which consists of a cube rendered at infinity with a sky texture projected onto it. Under the '''Object''' tab in the column of tool pages, find the [[Atmosphere Page]], and select the '''Skybox''' tool. In the '''Top''' viewport click anywhere to place a new skybox node in the world. Like everything that's rendered at infinity, the position of the node doesn't matter, so it's a good idea to place the skybox node outside the world's geometry so it doesn't obscure anything else and it can be easily found. The editor should now look like Figure 14. [[File:NewWorld14.png|thumb|center|960px|'''Figure 14.''' A skybox node has been added to the world.]] With the skybox node still selected, type Ctrl-I to open the Node Info window. Under the '''Skybox''' tab, check the box next to '''Render above horizon only''' because we are going to select a set of skybox textures that are designed to cover only the top half of the entire skybox cube. For the '''Positive X texture map name''' setting, click the button with three dots on the right side of the window, navigate to the <code>Data/The31st/sky</code> directory, and select <code>Cloudy1-A.tex</code>. For the next four settings, do the same thing and select variants <code>-B</code>, <code>-C</code>, <code>-D</code>, and <code>-E</code> of the same <code>Cloudy1</code> texture maps. This skybox does not have a component for the '''Negative Z texture map name''', so leave that setting blank. The Node Info window should now look like Figure 15. [[File:NewWorld15.png|thumb|center|960px|'''Figure 15.''' A skybox node has been added to the world.]] Click OK to return to the editor. One final step is necessary before the skybox will be visible. Double-click on the Infinite Zone node (or select it and type Ctrl-I). Then check '''Render skybox in this zone''' in the Node Info window and click OK. If you look upward in the '''Perspective''' viewport by right-clicking and dragging vertically, you should now see the sky above the horizon, and it should smoothly blend into the clear color that we previously chose below the horizon. == See Also == * [[World Editor]] * [[Material Editor]] * [[Connectors]] [[Category:Tutorials]] 217ac5208a35e5d621635c20130fb09acd0b41fd Category:Tutorials 14 150 152 2023-07-15T11:02:52Z Eric Lengyel 1 Created blank page wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Portal1.png 6 151 153 2023-07-15T11:04:26Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Portal2.png 6 152 154 2023-07-15T11:04:39Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Portal3.png 6 153 155 2023-07-15T11:04:53Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Portal4.png 6 154 156 2023-07-15T11:05:07Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Portal5.png 6 155 157 2023-07-15T11:05:19Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Portal6.png 6 156 158 2023-07-15T11:05:31Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Portal7.png 6 157 159 2023-07-15T11:05:42Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Portal Tutorial 0 158 160 2023-07-15T11:05:48Z Eric Lengyel 1 Created page with "In order to allow for arbitrarily large and complex environments, every sizable world built in the C4 Engine [[World Editor]] should be organized into multiple zones. The root node of a world is an infinitely large zone, and all other zones are contained within the root zone. When new zones are added to a world, they need to be connected by portals so that it's possible to see from one zone into another. This tutorial describes a simple example in which two rooms are con..." wikitext text/x-wiki In order to allow for arbitrarily large and complex environments, every sizable world built in the C4 Engine [[World Editor]] should be organized into multiple zones. The root node of a world is an infinitely large zone, and all other zones are contained within the root zone. When new zones are added to a world, they need to be connected by portals so that it's possible to see from one zone into another. This tutorial describes a simple example in which two rooms are connected by a pair of portals. To follow this tutorial, you need the <code>Data/Tutorial/world/Portal.wld</code> file that is included in the <code>C4-xxx-Data.zip</code> distribution. To enlarge any of the screenshots below, click on the thumbnail icon below the image. == Step A: Prepare Portal.wld == Open <code>Data/Tutorial/world/Portal.wld</code> in the [[World Editor]] by typing Ctrl-O or by entering <code>world world/Portal</code> into the [[Command Console]]. The World Editor will display the scene shown in Figure 1 containing two rooms with a doorway in between. [[File:Portal1.png|thumb|center|960px|'''Figure 1.''' The portal tutorial world looks like this when it's first opened in the [[World Editor]].]] This world contains two zones, each of which contains a very simple room with a light source in it. The world already contains portals that lead from each room into the other, so you'll need to delete them first if you want to follow the rest of this tutorial. A direct portal is shown as a greenish outline with green arrows attached to it. In the perspective viewport, portals are filled with a pattern that contains the word "PORTAL". (There are other types of portals that are different colors, but a direct portal is the basic type that lets you see from one room to another.) To delete the two portals in this world, simply select each one and hit the Delete key. To select the portals in some viewports, it may be necessary to disable geometry and zone selection using the '''[[Node Management Page]]''' so that other types of nodes aren't inadvertently selected. There's nothing blocking our view in the Perspective viewport, though, so type Ctrl-4 to make it fill the screen, and click on the green portal in the doorway. The editor should appear as shown in Figure 2. [[File:Portal2.png|thumb|center|960px|'''Figure 2.''' One of the portals in the world is selected.]] Hit the Delete key to delete the selected portal, and you'll notice that the back wall of the other room disappears because we can no longer see through the doorway. Hold the right mouse button in the Perspective viewport and use the WSAD keys to fly the camera through the door into the other room. The walls will appear when you've entered the other zone. Turn the camera around so you can see the doorway that you just went through, and select the other portal that looks back into the first room. The editor should appear as shown in Figure 3. Hit the Delete key to remove this portal from the world. [[File:Portal3.png|thumb|center|960px|'''Figure 3.''' The second portal in the world is selected.]] == Step B: Draw a New Portal == To fully connect the two zones, one portal needs to be added to the left room that looks into the right room, and another portal needs to be added to the right room that looks into the left room. (That is, portals are one-way.) We only have to draw one portal, and then the opposing portal can be created automatically by the editor. First, switch to the Top viewport by typing Ctrl-1. Deselect the '''Geometry''' type from the '''[[Node Management Page]]''' (under the Editor tab) if you haven't already done so. Now select the zone for the right room, and choose '''Set Target Zone''' from the '''Node''' menu (or type Ctrl-T) to make the selected zone the current target zone. The striped zone boundary enclosing the right room will turn green to indicate that it's the current target zone. (Whenever a new node is created in the World Editor, it is placed in the current target zone.) The editor should now appear as shown in Figure 4. [[File:Portal4.png|thumb|center|960px|'''Figure 4.''' The zone containing the right room has been selected and made to be the current target zone.]] Switch to the Front viewport by typing Ctrl-2. This looks at the level from the positive ''x'' axis, which points to the right in the Top viewport. The doorway can be seen in the center of the image. Select the '''Direct Portal''' tool from the '''[[Portals Page]]''' (under the Object tab), and draw a portal over the doorway as shown in Figure 5. You can click in any corner of the doorway and drag to the diagonally opposite corner. [[File:Portal5.png|thumb|center|960px|'''Figure 5.''' A new portal has been drawn over the doorway.]] Switch back to the Top viewport by typing Ctrl-1, and notice that the portal has been placed on the left boundary of the target zone. The portal can be anywhere in the space where the two zones overlap, so this is fine. == Step C: Connect the Portal == We need to connect the portal to the zone for the left room in order to see from the right zone to the left zone. To do this, select the '''Connect Tool''' at the top of the editor window or use the 5 key as a shortcut. The built-in <code>%Zone</code> connector will appear for the portal, and the editor should look like Figure 6. [[File:Portal6.png|thumb|center|960px|'''Figure 6.''' The <code>%Zone</code> connector is shown for the new portal in the Top viewport.]] Select the <code>%Zone</code> connector by clicking on its box. Then select the zone for the left zone, and type Ctrl-L to link them together. The editor should now appear as shown in Figure 7. [[File:Portal7.png|thumb|center|960px|'''Figure 7.''' The portal has been connected to the left zone.]] Switch to the Perspective viewport by typing Ctrl-4. We're still looking at the doorway from the back side, so we need to fly the camera back through to the other room by holding the right mouse button and using the WSAD keys. Once we're in the other room and the camera has been turned around, we can see our new portal. We can also see through to the other room now because the portal has been connected to the other zone. == Step D: Create the Opposing Portal == As we noticed when we switched to the Perspective viewport, we still can't see from the left room into the right room. There is no portal that looks in that direction yet, but creating one is as simple as pressing a button. Click on the green portal to select it, and then click the '''Create Opposing''' button in the '''[[Portals Page]]'''. The opposing portal is automatically created, placed in the left zone, and connected to the right zone. If you fly the camera back through the doorway and turn around, you can now see from the left zone into the right zone. == Common Problems with Portals == * When creating new zones, make sure that one zone isn't accidentally a subzone of another when you didn't intend it to be. You can tell by looking at the node hierarchy in the Scene Graph viewport. A zone can be reparented by dragging it in the Scene Graph viewport to the proper parent zone, which is usually to infinite zone at the root of the scene. * Make sure each portal is a subnode of the zone that it leads out of. This can also be checked in the Scene Graph viewport. * Make sure each portal is connected to the zone that it leads into. You can tell by selecting the portal and selecting the '''Connect Tool''' (or using the 5 key as a shortcut). The <code>%Zone</code> connector should point to the center of the destination zone. == See Also == * [[Portals Page]] * [[Zones Page]] * [[Connectors]] [[Category:Tutorials]] 742d8ff4d802860cae1ebb15dc2c0ce6f8f721de File:Oscillation1.png 6 159 161 2023-07-15T11:07:03Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Oscillation2.png 6 160 162 2023-07-15T11:07:20Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Oscillation3.png 6 161 163 2023-07-15T11:08:21Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Oscillation4.png 6 162 164 2023-07-15T11:08:33Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Oscillation5.png 6 163 165 2023-07-15T11:08:46Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Oscillation6.png 6 164 166 2023-07-15T11:08:56Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Oscillation Tutorial 0 165 167 2023-07-15T11:09:02Z Eric Lengyel 1 Created page with "This tutorial teaches you how to assign an [[Oscillation Controller]] to a node in a level. The Oscillation Controller is a specific type of controller that's built into the C4 Engine, and it causes a node to oscillate back and forth between two points with a velocity based on a sine wave. To follow this tutorial, you need the <code>Data/Tutorial/world/Oscillation.wld</code> file that is included in the <code>C4-xxx-Data.zip</code> distribution. To enlarge any of the s..." wikitext text/x-wiki This tutorial teaches you how to assign an [[Oscillation Controller]] to a node in a level. The Oscillation Controller is a specific type of controller that's built into the C4 Engine, and it causes a node to oscillate back and forth between two points with a velocity based on a sine wave. To follow this tutorial, you need the <code>Data/Tutorial/world/Oscillation.wld</code> file that is included in the <code>C4-xxx-Data.zip</code> distribution. To enlarge any of the screenshots below, click on the thumbnail icon below the image. == Step A: Open Oscillation.wld == Open <code>Data/Tutorial/world/Oscillation.wld</code> in the [[World Editor]] by typing Ctrl-O or by entering <code>world world/Oscillation</code> into the [[Command Console]]. The World Editor will display the scene shown in Figure 1 containing a room with two platforms separated by a lava pit. [[File:Oscillation1.png|thumb|center|960px|'''Figure 1.''' The oscillation tutorial world looks like this when it's first opened in the [[World Editor]].]] == Step B: Assign Oscillation Controller == There is a smaller platform near the center of the scene that sticks out above the lava. We are going to assign an Oscillation Controller to this geometry so that it moves back and forth above the lava pit and allows the player to safely cross to the other side. Click on this platform to select it, as shown in Figure 2. [[File:Oscillation2.png|thumb|center|960px|'''Figure 2.''' The geometry node to which we will assign an Oscillation Controller is selected.]] Once the geometry is selected, type Ctrl-I to open the Node Info window, and then click on the '''Controller''' tab. Select the '''Oscillation Controller''' from the list. There are three settings for the Oscillation Controller, a speed and two connectors. The '''Oscillation speed''' setting determines how fast the node oscillates back and forth, and it's measured in cycles per second. A value of 0.5 would mean that the node moves halfway through one complete cycle in one second, which corresponds to a period of two seconds for each complete cycle. This is pretty fast, so we'll enter a much smaller number like 0.05, which means it takes 20 seconds for the node to complete one full cycle and return to its starting position. The connector settings specify the names of the connectors that will be used to specify the starting and finishing positions for the oscillation, as described in the next step. We'll use the default values, so no changes need to be made to these settings. The controller settings should look like those shown in Figure 3. Leave the Node Info window open because we are going to add connectors in the next step. [[File:Oscillation3.png|thumb|center|960px|'''Figure 3.''' These are the settings for the [[Oscillation Controller]].]] == Step C: Create Start and Finish Connectors == Click on the '''Connectors''' tab in the Node Info window. We need to add two new [[Connectors|connectors]] to the oscillating node that will be connected to markers in the world that tell the controller how far to move the node. Click the '''New''' button at the bottom of the window twice. In the blank fields that appear under the Custom Connectors heading, enter "Start" and "Finish" (without quotes). Connector names are case-sensitive, so be sure to capitalize the first letter. One this has been done, the Node Info window should appear as shown in Figure 4. Click '''OK''' to save the node settings and return to the main editor. [[File:Oscillation4.png|thumb|center|960px|'''Figure 4.''' Two new [[Connectors|connectors]] named Start and Finish are added to the node.]] == Step D: Add Markers to the World and Connect == We now need to add two locator markers to the world that tell the Oscillation Controller how far to move its target node. Scroll down through the tool pages on the left side of the editor window with the mouse wheel until the '''Markers Page''' is visible. (Make sure the '''Object''' tab is selected.) Then select the '''Locator Marker''' tool in the upper-left corner of the '''Markers Page'''. Type Ctrl-1 to make the Top viewport fill the editor window, and zoom in a little with the mouse wheel. Click on the upper edge of the geometry that has the Oscillation Controller assigned to it (which should still be selected before clicking). This will place a new locator marker in the world. Click again on the lower edge of the stone platform on the opposite side of the lava pit. This will place a second locator marker in the world. After both markers have been created, the editor window should look like that shown in Figure 5. [[File:Oscillation5.png|thumb|center|960px|'''Figure 5.''' Two locator markers have been placed in the scene.]] The difference in the position of the two locator markers corresponds to the distance over which the node will move. The final task is to connect the geometry node to the two locator markers. Select the '''Connect Tool''' at the top of the editor window (or use the 5 key as a shortcut), and select the geometry node by clicking on it in the Top viewport. (The ceiling has been hidden in this world so that a click will go through to the platform geometry in the Top viewport.) You will now see the two connectors named Start and Finish attached to the geometry node. Click on the Start connector, then click on the first locator marker that was placed in the world, and type Ctrl-L to link them together. Repeat this process by clicking on the Finish connector, clicking on the second locator marker, and typing Ctrl-L to link those together. Once this is done, the editor window should appear as shown in Figure 6. [[File:Oscillation6.png|thumb|center|960px|'''Figure 6.''' The Start and Finish connectors have been connected to the two locator markers that were placed in the world.]] == Step E: Play the Level == You can now type Ctrl-P to save and play the level. You will see the platform moving back and forth above the lava pit, completing a full cycle every 20 seconds. If you're running the demo game, then you can walk the player onto the moving platform (or jump) when it's close enough to your side of the lava pit. The platform will carry the player to the other side where he can safely step off. == See Also == * [[Oscillation Controller]] * [[World Editor]] * [[Connectors]] [[Category:Tutorials]] 96382e9eee77b2f409d8a87a63734eb28cecf068 File:Terrain1.png 6 166 168 2023-07-15T11:10:47Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Terrain Tutorial 0 167 169 2023-07-15T11:17:45Z Eric Lengyel 1 Created page with "This tutorial guides you through the creation of a new terrain block and some basic terrain editing operations. For more general information about the terrain tools, see the [[Terrain]] article. To follow this tutorial, you need the <code>Data/Tutorial/world/Terrain.wld</code> file that is included in the C4 Engine distribution. To enlarge any of the screenshots below, click on the thumbnail icon below the image. == Step A: Open Terrain.wld == Open <code>Data/Tutoria..." wikitext text/x-wiki This tutorial guides you through the creation of a new terrain block and some basic terrain editing operations. For more general information about the terrain tools, see the [[Terrain]] article. To follow this tutorial, you need the <code>Data/Tutorial/world/Terrain.wld</code> file that is included in the C4 Engine distribution. To enlarge any of the screenshots below, click on the thumbnail icon below the image. == Step A: Open Terrain.wld == Open <code>Data/Tutorial/world/Terrain.wld</code> in the [[World Editor]] by typing Ctrl-O or by entering <code>world world/Terrain</code> into the [[Command Console]]. The World Editor should contain a nearly empty scene that looks like the screenshot shown in Figure 1. A skybox, infinite light, and physics node have already been added to the world. [[File:Terrain1.png|thumb|center|960px|'''Figure 1.''' The terrain tutorial world looks like this when it's first opened in the [[World Editor]].]] == Step B: Draw the Terrain Block == Select the Terrain Block tool in the Terrain Page under the Earth tab. In the Top viewport (the upper-left viewport), click on the origin and drag out a box that is 4 large grid squares on each side. The grid settings have been set up in this world so that each small grid square is 10 meters, and thus 4 large grid squares corresponds to 400 meters (or about a quarter mile). When you release the mouse button, a dialog box appears as shown in Figure 2. [[File:Terrain2.png|thumb|center|960px|'''Figure 2.''' When a new terrain block is drawn in the editor, a dialog appears to let you specify a height map and configure other settings.]] Select '''Import TGA Height Field''' from the '''Terrain Builders''' list. We are going to initialize the terrain block with height data from a grayscale <code>.tga</code> file. For the '''Height field image file''' setting, select the file <code>Tutorial/terrain/Terrain.tga</code> (which is located inside the <code>Import</code> folder). This file contains the height field used in an old demo level. To match the same vertical scale as in the demo, enter 80.0 in the '''Height scale (distance)''' setting. Click '''OK''', and after a couple seconds, the scene should appear as shown in Figure 3. [[File:Terrain3.png|thumb|center|960px|'''Figure 3.''' The initial form of the terrain is generated from the input height map.]] == Step C: Draw a Bridge == Type Ctrl-4 to make the Perspective viewport fill the editor window. Hold in the right mouse button in the Perspective viewport and use the WSAD keys to fly the camera closer to the terrain. Steer to the right slightly so that the small gully near the right end of the terrain is centered in the viewport as shown in Figure 4. [[File:Terrain4.png|thumb|center|960px|'''Figure 4.''' The Perspective viewport is centered on a small gully that we're going to draw a bridge over.]] Select the '''Additive Brush''' tool from the Terrain Page and make sure that the '''Cylindrical Brush''' shape is selected and the '''Horizontal Plane''' drawing plane is selected. We are going to draw a horizontal bridge connecting the left and right sides of the small gully visible in the perspective viewport. With the '''Additive Brush''' selected, click in the perspective viewport on one side of the gully at the height where the vertical center of the bridge should be. Hold the mouse button down and drag to the other side of the gully. The result should look like what is shown in Figure 5. You can undo with Ctrl-Z and redraw the bridge as many times as you like. [[File:Terrain5.png|thumb|center|960px|'''Figure 5.''' A bridge has been drawn across the gully with the additive terrain brush.]] == Step D: Apply Different Textures == Position the perspective viewport's camera so that you have a better view of the top of the bridge you just created. Select the '''Secondary Blend Brush''' tool in the Terrain Page, and select the '''Spherical Brush''' shape. Make sure that the '''Blend Strength''' slider is moved to the right so that a high percentage is displayed. This slider controls how the primary and secondary texture sets are blended together, with 0% being only the primary set, 100% being only the secondary set, and anything in between being a blend of the two sets. Click the leftmost texture in the secondary texture set. This is the texture applied to top-facing horizontal surfaces. Click on the top-right texture from the palette that appears to select a gray cinder/stones texture map. The editor window should now appear as shown in Figure 6. [[File:Terrain6.png|thumb|center|960px|'''Figure 6.''' The terrain tools have been prepared for painting a different texture on top of the bridge.]] With the '''Secondary Blend Brush''' tool still selected, click on one end of the top of the bridge and drag to the other end. The ground texture should change to stone as shown in the Figure 7. You may undo and redraw the texture if necessary. [[File:Terrain7.png|thumb|center|960px|'''Figure 7.''' The texture on top of the bridge has been changed with the secondary blend brush.]] Now reposition the camera so that you can see beneath the bridge. Change the drawing plane to '''Follow Surface''' in the Terrain Page as shown in Figure 8. Click on the leftmost texture in the secondary texture set again, and select the brown dirt texture map. [[File:Terrain8.png|thumb|center|960px|'''Figure 8.''' The terrain tools have been prepared for painting a different texture beneath the bridge.]] Click on the ground close to the camera and drag the mouse down through the center of the gully. The brush will follow the terrain surface and change the texture of the surface beneath it. You can use multiple brush strokes or drag the brush back and forth to make the path wider. The scene should look like the image shown in Figure 9. [[File:Terrain9.png|thumb|center|960px|'''Figure 9.''' The texture beneath the bridge has been changed with the secondary blend brush.]] == See Also == * [[Terrain]] * [[Terrain Palettes]] * [[World Editor]] [[Category:Tutorials]] bb01eaf64f149d788e6e41322d8cae30dc0c2057 File:Terrain2.png 6 168 170 2023-07-15T11:19:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Terrain3.png 6 169 171 2023-07-15T11:19:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Terrain4.png 6 170 172 2023-07-15T11:19:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Terrain5.png 6 171 173 2023-07-15T11:19:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Terrain8.png 6 172 174 2023-07-15T11:19:11Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Terrain9.png 6 173 175 2023-07-15T11:19:11Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Terrain6.png 6 174 176 2023-07-15T11:19:11Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Terrain7.png 6 175 177 2023-07-15T11:19:11Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Water Tutorial 0 176 178 2023-07-15T11:21:34Z Eric Lengyel 1 Created page with "This tutorial guides you through the creation of a new water surface with reflection and refraction effects applied. To follow this tutorial, you need the <code>Data/Tutorial/world/Water.wld</code> file that is included in the C4 Engine distribution. To enlarge any of the screenshots below, click on the thumbnail icon below the image. == Step A: Open Water.wld == Open <code>Data/Tutorial/world/Water.wld</code> in the [[World Editor]] by typing Ctrl-O or by entering <..." wikitext text/x-wiki This tutorial guides you through the creation of a new water surface with reflection and refraction effects applied. To follow this tutorial, you need the <code>Data/Tutorial/world/Water.wld</code> file that is included in the C4 Engine distribution. To enlarge any of the screenshots below, click on the thumbnail icon below the image. == Step A: Open Water.wld == Open <code>Data/Tutorial/world/Water.wld</code> in the [[World Editor]] by typing Ctrl-O or by entering <code>world world/Water</code> into the [[Command Console]]. The World Editor should contain a scene that looks like the screenshot shown in Figure 1. The world already contains a ground plane and the boundary walls for a pool of water. [[File:Water1.png|thumb|center|960px|'''Figure 1.''' The water tutorial world looks like this when it's first opened in the [[World Editor]].]] == Step B: Draw the water surface == Make sure that the '''Water''' material is selected in the Material page under the Material tab. Then switch back to the Object tab and select the Plate Geometry tool in the [[Geometries Page]]. Type Ctrl-1 to make the Top viewport fill the editor window. You may want to zoom in a little bit with the mouse wheel to make the fine gridlines appear. Draw a new plate geometry by clicking in one corner of the pool a dragging to the opposite corner. Type Ctrl-1 again to show all four viewports, and the world should appear as shown in Figure 2. [[File:Water2.png|thumb|center|960px|'''Figure 2.''' The world looks like this after the water surface has been drawn.]] == Step C: Set water surface perspective mask == With the plate geometry representing the water surface still selected, type Ctrl-I to open the Node Info window. Switch to the Node tab and scroll down to the bottom so that all of the perspective mask settings are visible. We don't want the water itself to be rendered in the reflection or refraction image, so we need to uncheck all of the perspectives that include "reflection" or "refraction", as shown in Figure 3. After this is done, click OK. [[File:Water3.png|thumb|center|960px|'''Figure 3.''' All of the reflection and refraction perspectives have been unchecked for the water surface.]] == Step D: Draw a reflection portal == Select the Indirect Portal tool in the [[Portals Page]]. In the Top viewport, drag out the same square that you previously drew for the water surface, so that the portal covers the same area. With the portal still selected, type Ctrl-I to open the Node Info window. Under the Portal tab, check the '''Camera uses oblique frustum''' box, as shown in Figure 4. Under the Node tab, uncheck the perspectives for refraction so that the reflection portal is not considered when the refraction image is rendered. Click OK. [[File:Water4.png|thumb|center|960px|'''Figure 4.''' These are the settings for the reflection portal.]] == Step E: Draw a refraction portal == Using the Indirect Portal tool again, draw another portal over the same area, and then type Ctrl-I to open the Node Info window. Under the Portal tab, check the '''Camera uses oblique frustum''' box and change the '''Portal target buffer''' to '''Refraction'''. Under the Node tab, uncheck the perspectives for reflection so that the refraction portal is not considered when the reflection image is rendered. Click OK, and type Ctrl-4 to switch to the perspective viewport. It should look like Figure 5, where the bottom of the pool can be seen through the water surface now. [[File:Water5.png|thumb|center|960px|'''Figure 5.''' The water surface looks like this after the reflection and refraction portals have been drawn.]] == Step F: Set portal offsets == Hide both of the indirect portals so that the purple color no longer appears in the perspective viewport. (Select both indirect portals in the scene graph viewport and type Ctrl-H.) Switch to the perspective viewport by typing Ctrl-4 and take a moment to fly the camera around by holding in the right mouse button and using the WSAD keys. Notice that some white background color leakage is visible where the water surface meets the edges of the pool. This is due to the geometry being clipped at the water plane. To correct this problem, select both portals, type Ctrl-I, and change the '''Portal plane offset''' setting to 0.1. Click OK, and hide both portals again. The water surface should now appear as shown in Figure 6. [[File:Water6.png|thumb|center|960px|'''Figure 6.''' The water surface looks like this near the edges of the pool after the portal offsets have been set.]] == Step G: Add an underwater fog space == The water is extremely clear at this point. To make it murky, we can add a fog space that will only affect the refraction image. There is already one fog space applied to the main scene. Multiple fog spaces can be used simultaneously as long as they apply to different perspectives. The existing fog space has already been configured to not be rendered in the refraction image. Select the Fog Space tool in the [[Atmosphere Page]] under the Object tab. In the Top viewport, drag out the same area again, covering the water surface. Type Ctrl-I to open the Node Info window. Under the Node tab, uncheck all of the perspectives ''except'' the refraction perspectives, as shown in Figure 7. Now switch to the Fog Space tab, and make the following changes to the fog settings. Set the '''Fog color''' to (75,90,55) for a greenish-brown color (or choose your own water color). Set the '''Fog density''' to 1.0, and set the '''Density function''' to '''Linear'''. Click OK. After hiding the underwater fog space, the pool should look like what's shown in Figure 8. [[File:Water7.png|thumb|center|960px|'''Figure 7.''' The settings for the underwater fog space cause it to be rendered only in the refraction perspective.]] [[File:Water8.png|thumb|center|960px|'''Figure 8.''' This is the final appearance of the pool.]] == Additional Notes == This tutorial was set up so that the water surface, indirect portals, and fog space were all drawn in the ''x''-''y'' plane where ''z'' = 0. These nodes will often need to be moved vertically to the desired height. The important part is that they are all coplanar. The overall intensity of the reflection and refraction images rendered on the water surface is controlled by the reflection color and refraction color settings in the [[Material Editor]]. For example, to see a must brighter reflection in the water, double-click on the Water material to open the Material Editor, switch to the Ambient tab, and make the '''Reflection color''' brighter. This tutorial used a perfectly flat surface for the water. To create a surface with physically-simulated waves, a water block can be drawn instead, and buoyancy can be added by using a field node. These will be covered in a separate tutorial. == See Also == * [[World Editor]] * [[Material Editor]] [[Category:Tutorials]] fdd5b1021a95698258f70e70b51447a3274d1079 File:Water1.png 6 177 179 2023-07-15T11:22:24Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Water3.png 6 178 180 2023-07-15T11:22:24Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Water2.png 6 179 181 2023-07-15T11:22:24Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Water4.png 6 180 182 2023-07-15T11:22:24Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Water7.png 6 181 183 2023-07-15T11:22:24Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Water6.png 6 182 184 2023-07-15T11:22:25Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Water5.png 6 183 185 2023-07-15T11:22:25Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Water8.png 6 184 186 2023-07-15T11:22:26Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Teleport Tutorial 0 185 187 2023-07-15T11:23:25Z Eric Lengyel 1 Created page with "This tutorial describes the method used to create an indirect portal that can see another part of a level, apply a material with animated waves to the portal, and make the destination image float up and down. This tutorial doesn't have you modify a world, but instead examines what has been done in a fully functional example. To follow this tutorial, you need the <code>Data/Tutorial/world/Teleport.wld</code> file that is included in the C4 Engine distribution. To enlarg..." wikitext text/x-wiki This tutorial describes the method used to create an indirect portal that can see another part of a level, apply a material with animated waves to the portal, and make the destination image float up and down. This tutorial doesn't have you modify a world, but instead examines what has been done in a fully functional example. To follow this tutorial, you need the <code>Data/Tutorial/world/Teleport.wld</code> file that is included in the C4 Engine distribution. To enlarge any of the screenshots below, click on the thumbnail icon below the image. == Step A: Open Teleport.wld == Open <code>Data/Tutorial/world/Teleport.wld</code> in the [[World Editor]] by typing Ctrl-O or by entering <code>world world/Teleport</code> into the [[Command Console]]. The World Editor will display the scene shown in Figure 1 where the camera is inside one of two big rooms connected by long hallways. The remote portal is visible right away as a doorway with a wavy greenish material through which you can see the other big room in the level. [[File:Teleport1.png|thumb|center|960px|'''Figure 1.''' The teleport tutorial world looks like this when it's first opened in the [[World Editor]].]] Take a moment to play the world by typing Ctrl-P in the editor. (You'll need to be running the demo game in order to walk the player through the level.) Walk the player up to the portal using the standard WSAD keys and mouse to move. Notice that the material has a greenish tint and that animated waves are distorting the image of a distant room that can be seen through the portal. The image is also slowly floating up and down because an [[Oscillation Controller]] has been assigned to the destination marker (see Step C below). In the demo game, the player can teleport to the other room by running into the portal. This particular behavior is defined by game-specific code and is not built into the core engine. There are several examples of how to teleport characters and projectiles in the source code for the demo game. To return to the World Editor, open the console with the tilde key and type Ctrl-Shift-P. == Step B: Examine the Indirect Portal == The image of the other room is rendered into the refraction buffer through an indirect portal in the world. In this step, we will look at the settings that have been applied to this portal in order to render the image we want. First, we need to select the indirect portal. It's embedded in the geometry for the doorway, so we need to deselect the geometry type from the current selection mask. The [[Node Management Page]] can be found under the Editor tab, and it lists all of the various types of nodes. Unchecking the Geometry type indicates that geometries can no longer be selected. Now switch to the Top viewport by typing Ctrl-1, and zoom in a little on the doorway that can be seen on the left wall of the rightmost large room. There is a purple line with arrows pointing to the left. This is the indirect portal. Click on the line to select it, and the editor window should appear as shown in Figure 2. [[File:Teleport2.png|thumb|center|960px|'''Figure 2.''' The indirect portal has been selected in the Top viewport.]] Once the indirect portal has been selected, type Ctrl-I to open the Node Info window. The settings under the Portal tab should appear as shown in Figure 3. All of the settings use the default values except for two. First, the '''Portal target buffer''' setting has been set to '''Refraction'''. This tells the engine to render the image seen through the portal into a separate frame buffer that holds the image accessed when an ambient refraction color is specified by a material. Second, the '''Camera uses oblique frustum''' box has been checked. This tells the engine to use a special projection matrix trick to align the near plane of the indirect camera frustum with the plane of the portal to clip geometry that would otherwise stick out in front of the plane. [[File:Teleport3.png|thumb|center|960px|'''Figure 3.''' These are the settings under the Portal tab for the indirect portal node.]] Now click on the Connectors tab in the Node Info window, and you will see the settings shown in Figure 4. The indirect portal uses one built-in connector named <code>%Zone</code> and two custom connectors named '''Local''' and '''Remote'''. The <code>%Zone</code> connector is used to link the portal to the destination zone, and the '''Local''' and '''Remote''' connectors are linked to markers that define the transform between the portal's local coordinate system and the destination where the image will actually be rendered. These are discussed in the next step. [[File:Teleport4.png|thumb|center|960px|'''Figure 4.''' These are the settings under the Connectors tab for the indirect portal node.]] == Step C: Examine the Locator Markers == Close the Node Info window by clicking the Cancel button or hitting the Escape key. Select the Connect Tool by clicking on it at the top of the editor window or using the 5 key as a shortcut. The three connectors attached to the indirect portal will appear along with lines of arrows showing what nodes they are connected to, as shown in Figure 5. Zoom out a little to see all of the connected nodes. [[File:Teleport5.png|thumb|center|960px|'''Figure 5.''' The indirect portal is connected to three other nodes in the level.]] You can double-click on any of the connectors to select the node that it is connected to. The <code>%Zone</code> connector is connected to the zone that contains the big room on the left side of the level. This connection tells the engine that the indirect camera should be placed in this zone when rendering the image that can be seen through the portal. The '''Local''' and '''Remote''' connectors are connected to locator markers that, taken together as a pair, tell the engine how to transform the main camera into the coordinate system in which the destination image will be rendered. The marker connected to the '''Local''' connector specifies a reference point and orientation on the portal itself, and the marker connected to the '''Remote''' connector specifies the corresponding point and orientation at the destination. The marker at the destination can be moved or rotated to instantly change the camera transform for the image seen through the portal. If you select the locator marker connected to the '''Remote''' connector by double-clicking on the connector, then you can see that it has two connectors of its own named '''Start''' and '''Finish'''. These are used in conjunction with an [[Oscillation Controller]] that has been assigned to the marker that makes it float up and down for added effect. See the [[Oscillation Tutorial]] for more information about oscillating nodes. == Step D: Examine the Portal Material == Change the main viewport to the Perspective view by typing Ctrl-4, and switch to the ordinary Select Tool by selecting it at the top of the editor window or using the 1 key as a shortcut. Re-enable geometry node selection by checking the Geometry type in the Node Management Page, and disable portal node selection by unchecking the Portal type. Now click on the geometry covering the interior of the doorway where the indirect portal is. You should now see a rectangular geometry selected as shown in Figure 6. [[File:Teleport6.png|thumb|center|960px|'''Figure 6.''' The geometry covering the indirect portal has been selected.]] Select the Material Pickup tool from the [[Material Page]], and click on the selected geometry to change the current material to the material used by the geometry. (We didn't actually have to select the geometry first, but doing so makes it obvious where to click to grab the material.) The material used on the portal geometry just uses the standard attribute settings and does not require that you use the [[Shader Editor]]. Open the [[Material Editor]] by double-clicking on the selected material. Under the Diffuse tab, shown in Figure 7, the Diffuse color attribute has been set to the green color that is responsible for the green tint seen in the portal. The Normal map (primary) and Normal map (secondary) attributes have been set to two water wave textures that can be found in the <code>Data/The31st/texture/</code> directory. Notice that the two normal maps use different texture coordinates. These are animated independently so that the normal maps are combined in a random-looking way. [[File:Teleport7.png|thumb|center|960px|'''Figure 7.''' The Diffuse tab for the portal material shows the diffuse reflection color and normal maps.]] Under the Ambient tab, shown in Figure 8, the Refraction color attribute has been set to a brighter greenish color. This is multiplied by the colors in the refraction image to determine how much light gets through and what color it is. The Refraction offset scale attribute determines how large the distortion caused by the normal maps is. Higher numbers correspond to a more intense distortion effect. [[File:Teleport8.png|thumb|center|960px|'''Figure 8.''' The Ambient tab for the portal material shows the refraction color and offset scale.]] Under the Texcoords tab, shown in Figure 9, the scales of both sets of texture coordinates has been set to 0.25. Smaller numbers here correspond to larger waves. Animation has been enabled for both sets of texture coordinates, and the direction and speed have been set to different values so that the textures move in different directions. These values can be changed freely to modify the animation of the wavy effect. [[File:Teleport9.png|thumb|center|960px|'''Figure 9.''' The Texcoords tab for the portal material shows the texture map animation parameters.]] == See Also == * [[Oscillation Tutorial]] * [[World Editor]] * [[Material Editor]] * [[Connectors]] [[Category:Tutorials]] 55946cde1edd58ee1b34db2405e92575608ef453 File:Teleport2.png 6 186 188 2023-07-15T11:23:42Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Teleport3.png 6 187 189 2023-07-15T11:23:42Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Teleport4.png 6 188 190 2023-07-15T11:23:42Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Teleport5.png 6 189 191 2023-07-15T11:23:42Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Teleport1.png 6 190 192 2023-07-15T11:23:43Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Teleport7.png 6 191 193 2023-07-15T11:23:43Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Teleport8.png 6 192 194 2023-07-15T11:23:43Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Teleport9.png 6 193 195 2023-07-15T11:23:43Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Teleport6.png 6 194 196 2023-07-15T11:23:43Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Simpleball.jpg 6 195 197 2023-07-15T11:25:16Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Simple Games 0 196 198 2023-07-15T11:25:20Z Eric Lengyel 1 Created page with "__NOTOC__ The C4 Engine ships with two basic game projects called <code>SimpleBall</code> and <code>SimpleChar</code>. Both are made up of two files that are heavily commented and represent nearly the minimum amount of code that needs to be written to have a working game module. You can tell the engine to load one of these game module by editing the file <code>Data/Engine/game.cfg</code> and changing the value of the variable <code>gameModuleName</code> to either <code>..." wikitext text/x-wiki __NOTOC__ The C4 Engine ships with two basic game projects called <code>SimpleBall</code> and <code>SimpleChar</code>. Both are made up of two files that are heavily commented and represent nearly the minimum amount of code that needs to be written to have a working game module. You can tell the engine to load one of these game module by editing the file <code>Data/Engine/game.cfg</code> and changing the value of the variable <code>gameModuleName</code> to either <code>"SimpleBall"</code> or <code>"SimpleChar"</code>. To return to the large demo game, change <code>gameModuleName</code> back to <code>"The31st"</code>. == SimpleBall == [[File:Simpleball.jpg|right|frame|'''Figure 1.''' The SimpleBall game shows a room with dozens of glowing balls bouncing around.]] The '''SimpleBall''' game demonstrates a basic rigid body controller and particle system implementation. It also has controls for moving a spectator camera and registering a model type, controller type, and locator type. When the SimpleBall module starts, it displays a small dialog box. Click the '''Start''' button to load a world that demonstrates the basic functionality implemented in the game. The "SimpleBall" world contains dozens of yellow bouncing balls in a room, as shown in Figure 1, and every ball can collide with the environment or any other ball. The motion of the balls is controlled by the physics system, and the SimpleBall code responds to collisions by generating some sparks as a small particle system. == SimpleChar == The '''SimpleChar''' game demonstrates a basic character controller and third-person chase camera. The character is able to perform basic interactions with the environment. To load a level after starting SimpleChar, you'll need to open the [[Command Console]] with the tilde key then use the <code>load</code> command. For example, type load <code>world/Teleport</code> to load the <code>Tutorials/world/Teleport.wld</code> world.) The SimpleChar tutorial does not have any user interface, and the gray screen shown at start-up is normal. To quit this game, use one of the methods described in [[Quick Tour]]. When the SimpleChar module is running, you will be able to run the soldier model around the world using the WSAD keys and the mouse. If the movement keys don't seem to work, make sure the strip at the bottom of the screen is not visible by pressing the Escape key. If the character is close enough to an interactive object such as gate that can be opened or a level that can be pulled, pointing toward the object and clicking the mouse will activate the controller attached to it. Note that many of the physical objects in various worlds will not work as they do in the demo game because they use special controllers that are not defined in the SimpleChar game. It is not a bug if you can walk through a crate in SimpleChar when that crate could be broken by the axe in the demo game, for example. [[Category:Tutorials]] ea78fd0f7e7212cf54723f1b111a5f7c5e4293a1 File:Editor effects.png 6 197 199 2023-07-15T11:27:20Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor find.png 6 198 200 2023-07-15T11:27:20Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor geometries.png 6 199 201 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor grid.png 6 200 202 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor impostors.png 6 201 203 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor info.png 6 202 204 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor landscaping.png 6 203 205 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor lights.png 6 204 206 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor markers.png 6 205 207 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor nodemanagement.png 6 206 208 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor material.png 6 207 209 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor paint.png 6 208 210 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor particles.png 6 209 211 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor paths.png 6 210 212 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor physics.png 6 211 213 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor placement.png 6 212 214 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor portals.png 6 213 215 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor sources.png 6 214 216 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor terrain.png 6 215 217 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor texturemapping.png 6 216 218 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor transform.png 6 217 219 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor triggers.png 6 218 220 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor viewports.png 6 219 221 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor water.png 6 220 222 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Editor zones.png 6 221 223 2023-07-15T11:27:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Flag backfaces.png 6 222 224 2023-07-15T11:28:19Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Flag cap.png 6 223 225 2023-07-15T11:28:19Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Flag center.png 6 224 226 2023-07-15T11:28:19Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Flag models.png 6 225 227 2023-07-15T11:28:19Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Connectors.png 6 226 228 2023-07-15T11:28:19Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Flag worlds.png 6 227 229 2023-07-15T11:28:19Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Importanimation.png 6 228 230 2023-07-15T11:28:20Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Materialeditor.png 6 229 231 2023-07-15T11:28:20Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Normalimporter.png 6 230 232 2023-07-15T11:28:20Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Fontimporter.png 6 231 233 2023-07-15T11:28:20Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Movieimporter.png 6 232 234 2023-07-15T11:28:20Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Landscapingeditor.png 6 233 235 2023-07-15T11:28:20Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Paneleditor.png 6 234 236 2023-07-15T11:28:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Modelviewer.png 6 235 237 2023-07-15T11:28:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Scripteditor.png 6 236 238 2023-07-15T11:28:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:OpenDDL.png 6 237 239 2023-07-15T11:28:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Movieplayer.png 6 238 240 2023-07-15T11:28:21Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader abs.png 6 239 241 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader add.png 6 240 242 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader alphaoutput.png 6 241 243 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader alphatestoutput.png 6 242 244 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader ambientoutput.png 6 243 245 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader avg.png 6 244 246 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader bloomoutput.png 6 245 247 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader combinenormals.png 6 246 248 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader composite.png 6 247 249 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader constantcolor.png 6 248 250 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader constantscalar.png 6 249 251 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader constantvector.png 6 250 252 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader cos.png 6 251 253 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader deltadepth.png 6 252 254 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader diffuse.png 6 253 255 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader div.png 6 254 256 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader dp3.png 6 255 257 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader dp4.png 6 256 258 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader emissionoutput.png 6 257 259 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader environmentoutput.png 6 258 260 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader ex2.png 6 259 261 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader expand.png 6 260 262 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader flr.png 6 261 263 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader fragmentdepth.png 6 262 264 2023-07-15T11:29:07Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader frc.png 6 263 265 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader glowoutput.png 6 269 271 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader glyph.png 6 270 272 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader horizon.png 6 271 273 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader impostornormal.png 6 273 275 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader impostortexture.png 6 274 276 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader invert.png 6 275 277 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader kill.png 6 276 278 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader lg2.png 6 277 279 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader lightingoutput.png 6 278 280 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader linearramp.png 6 279 281 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader lrp.png 6 280 282 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader mad.png 6 281 283 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader magnitude3d.png 6 282 284 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader max.png 6 283 285 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader merge2d.png 6 284 286 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader merge3d.png 6 285 287 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader merge4d.png 6 286 288 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader min.png 6 288 290 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader mul.png 6 289 291 2023-07-15T11:29:08Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader normalize3d.png 6 290 292 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader normalmap.png 6 291 293 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader objectbitangent.png 6 292 294 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader objecthalfway.png 6 293 295 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader objectlight.png 6 294 296 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader objectnormal.png 6 295 297 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader objectposition.png 6 296 298 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader objecttangent.png 6 297 299 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader objectview.png 6 298 300 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader painttexcoord.png 6 299 301 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader painttexture.png 6 300 302 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader parallax.png 6 301 303 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader pow.png 6 302 304 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader primitivefacing.png 6 303 305 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader rcp.png 6 304 306 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader reflectionoutput.png 6 305 307 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader reflectvector.png 6 306 308 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader refractionoutput.png 6 307 309 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader round.png 6 308 310 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader rsq.png 6 309 311 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sat.png 6 310 312 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader seq.png 6 311 313 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sge.png 6 312 314 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sgt.png 6 313 315 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sin.png 6 314 316 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sle.png 6 315 317 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader slt.png 6 316 318 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader smooth.png 6 317 319 2023-07-15T11:29:09Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sne.png 6 318 320 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader specular.png 6 319 321 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sqrt.png 6 320 322 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader steep.png 6 321 323 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sub.png 6 322 324 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader tangenthalfway.png 6 323 325 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader tangentlight.png 6 324 326 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader tangenttoworld.png 6 325 327 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader tangentview.png 6 326 328 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader terraindiffuse.png 6 327 329 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader terrainenvironmentoutput.png 6 328 330 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader terrainnormal1.png 6 329 331 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader terrainspecular.png 6 330 332 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader terraintexture.png 6 331 333 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader texcoord1.png 6 332 334 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader texcoord2.png 6 333 335 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader texturemap.png 6 334 336 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader time.png 6 335 337 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader vertexcolor.png 6 336 338 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader vertexgeometry.png 6 337 339 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader worldbitangent.png 6 338 340 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader worldnormal.png 6 339 341 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader worldposition.png 6 340 342 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader worldtangent.png 6 341 343 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader xpd.png 6 342 344 2023-07-15T11:29:10Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Soundimporter.png 6 343 345 2023-07-15T11:29:48Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Slug.png 6 344 346 2023-07-15T11:29:48Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shafts.jpg 6 345 347 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Soundplayer.png 6 346 348 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool boxselect.png 6 347 349 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool boxzoom.png 6 348 350 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Terrainpalette.png 6 349 351 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool camera.png 6 350 352 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool connect.png 6 351 353 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Textureimporter.png 6 352 354 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shadereditor.png 6 353 355 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool light.png 6 354 356 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool move.png 6 355 357 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool orbit.png 6 356 358 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool resize.png 6 357 359 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool rotate.png 6 358 360 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool scroll.png 6 359 361 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool section.png 6 360 362 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool select.png 6 361 363 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Textureviewer.png 6 362 364 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool surface.png 6 363 365 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool texoffset.png 6 364 366 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool texscale.png 6 365 367 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Tool zoom.png 6 366 368 2023-07-15T11:29:49Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget border.png 6 367 369 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget camera.png 6 368 370 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget check.png 6 369 371 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget color.png 6 370 372 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget config.png 6 371 373 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget edittext.png 6 372 374 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget hyperlink.png 6 373 375 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget icon.png 6 374 376 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget image.png 6 376 378 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget imagebutton.png 6 377 379 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget line.png 6 378 380 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget list.png 6 379 381 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget menubar.png 6 380 382 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget movie.png 6 381 383 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget multipane.png 6 382 384 2023-07-15T11:30:02Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget paint.png 6 383 385 2023-07-15T11:30:03Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget password.png 6 384 386 2023-07-15T11:30:03Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget picture.png 6 385 387 2023-07-15T11:30:03Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget popupmenu.png 6 386 388 2023-07-15T11:30:03Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget progress.png 6 387 389 2023-07-15T11:30:03Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget pushbutton.png 6 388 390 2023-07-15T11:30:03Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget quad.png 6 389 391 2023-07-15T11:30:03Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget radio.png 6 390 392 2023-07-15T11:30:03Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget scroll.png 6 391 393 2023-07-15T11:30:03Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget slider.png 6 392 394 2023-07-15T11:30:03Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget stroke.png 6 393 395 2023-07-15T11:30:03Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget text.png 6 394 396 2023-07-15T11:30:03Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget textbutton.png 6 395 397 2023-07-15T11:30:03Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Widget viewport.png 6 396 398 2023-07-15T11:30:03Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Worldeditor.png 6 397 399 2023-07-15T11:30:04Z Eric Lengyel 1 Uploaded with [[mw:Special:MyLanguage/Extension:SimpleBatchUpload|SimpleBatchUpload]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Resource Packer 0 398 400 2023-07-15T11:32:38Z Eric Lengyel 1 Created page with "__NOTOC__ The '''Resource Packer''' is a plugin that ships with the C4 Engine, and it is used to create pack files in the engine's proprietary <code>.pak</code> format. For information about how pack files work, see [[Pack Files and Virtual Directories]]. == Creating a Pack File == The console command <code>pack ''name''</code> is used to create a pack file, where ''name'' is the name of a top-level subfolder inside the <code>Data</code> folder. Once a pack file has b..." wikitext text/x-wiki __NOTOC__ The '''Resource Packer''' is a plugin that ships with the C4 Engine, and it is used to create pack files in the engine's proprietary <code>.pak</code> format. For information about how pack files work, see [[Pack Files and Virtual Directories]]. == Creating a Pack File == The console command <code>pack ''name''</code> is used to create a pack file, where ''name'' is the name of a top-level subfolder inside the <code>Data</code> folder. Once a pack file has been created, the folder from which it was made can be deleted, and the Resource Manager will then fetch resources from the pack file. (The pack file takes precedence over the folder from which it was created.) The original files from which a pack file was created cannot be recovered from the pack file, so they should be saved in a separate location for future use. Pack files are generally created when it is time to ship a final product. == See Also == * [[Pack Files and Virtual Directories]] 083260ba12cad229f14b915588f6f159892b3a9f String Importer 0 399 401 2023-07-15T11:33:14Z Eric Lengyel 1 Created page with "The '''String Importer''' is a plugin that ships with the C4 Engine, and it generates string table resources in the engine's proprietary <code>.str</code> file format. The String Importer can be run by choosing '''Import String Table''' from the [[C4 Menu]] or by typing <code>istring [''name'']</code> in the [[Command Console]]. If the '''Import String Table''' menu item is selected (or name is omitted from the console command), then a dialog appears to let you select a..." wikitext text/x-wiki The '''String Importer''' is a plugin that ships with the C4 Engine, and it generates string table resources in the engine's proprietary <code>.str</code> file format. The String Importer can be run by choosing '''Import String Table''' from the [[C4 Menu]] or by typing <code>istring [''name'']</code> in the [[Command Console]]. If the '''Import String Table''' menu item is selected (or name is omitted from the console command), then a dialog appears to let you select a text file from the Import directory. The text file to be imported must conform to the [[OpenDDL]] format. A single data structure type called <code>Entry</code> is used to declare each string together with its ID as follows. Entry (id = 'abcd') {string {"The string."}} The <code>id</code> property accepts a 32-bit unsigned integer that is usually expressed as a four-character code, as in the above example. The identifiers are used to select strings in the imported resource. Strings may be organized into a hierarchy that is up to five levels deep by including <code>Entry</code> structures inside the data payloads of other <code>Entry</code> structures as in the following example. Entry (id = 'type') { string {"Top-level string"} Entry (id = 'abcd') {string {"Substring 1"}} Entry (id = 'efgh') {string {"Substring 2"}} } Here, the string with ID equal to <code>StringID('type')</code> is "Top-level string", the string with ID equal to <code>StringID('type', 'abcd')</code> is "Substring 1", and the string with ID equal to <code>StringID('type', 'efgh')</code> is "Substring 2". == See Also == * [[String Tables]] 31bef3107d838f0b646969b9a4561ada2de3766e OpenDDL 0 400 402 2023-07-15T11:35:31Z Eric Lengyel 1 Created page with "[[File:OpenDDL.png|right|thumb|640px|'''Figure 1.''' [http://openddl.org/ The Open Data Description Language.]]] The Open Data Description Language (OpenDDL) is a generic text-based data language used for a variety of purposes by the C4 Engine. == See Also == * [http://openddl.org/ openddl.org] * [[Open Game Engine Exchange]]" wikitext text/x-wiki [[File:OpenDDL.png|right|thumb|640px|'''Figure 1.''' [http://openddl.org/ The Open Data Description Language.]]] The Open Data Description Language (OpenDDL) is a generic text-based data language used for a variety of purposes by the C4 Engine. == See Also == * [http://openddl.org/ openddl.org] * [[Open Game Engine Exchange]] 8f27a53cd6c77a82e4362caca691729d33141363 404 402 2023-07-15T11:36:57Z Eric Lengyel 1 Redirected page to [[Open Data Description Language]] wikitext text/x-wiki #REDIRECT [[Open Data Description Language]] 8ff9ba14602daeaed4bfde972c363b3c099f816b Open Game Engine Exchange 0 401 403 2023-07-15T11:35:53Z Eric Lengyel 1 Created page with "The '''Open Game Engine Exchange (OpenGEX)''' format is a text-based file format designed to facilitate the transfer of complex scene data between applications such as modeling tools and game engines. The C4 Engine [[World Editor]] can import files in the OpenGEX format after they have been exported from programs such as 3ds max and Maya. == See Also == * [http://opengex.org/ opengex.org] * [[Open Data Description Language]]" wikitext text/x-wiki The '''Open Game Engine Exchange (OpenGEX)''' format is a text-based file format designed to facilitate the transfer of complex scene data between applications such as modeling tools and game engines. The C4 Engine [[World Editor]] can import files in the OpenGEX format after they have been exported from programs such as 3ds max and Maya. == See Also == * [http://opengex.org/ opengex.org] * [[Open Data Description Language]] da76d4bc0f0ccaeb3cc30b69b7bcdb364ec323d9 Open Data Description Language 0 402 405 2023-07-15T11:37:04Z Eric Lengyel 1 Created page with "[[File:OpenDDL.png|right|thumb|640px|'''Figure 1.''' [http://openddl.org/ The Open Data Description Language.]]] The Open Data Description Language (OpenDDL) is a generic text-based data language used for a variety of purposes by the C4 Engine. == See Also == * [http://openddl.org/ openddl.org] * [[Open Game Engine Exchange]]" wikitext text/x-wiki [[File:OpenDDL.png|right|thumb|640px|'''Figure 1.''' [http://openddl.org/ The Open Data Description Language.]]] The Open Data Description Language (OpenDDL) is a generic text-based data language used for a variety of purposes by the C4 Engine. == See Also == * [http://openddl.org/ openddl.org] * [[Open Game Engine Exchange]] 8f27a53cd6c77a82e4362caca691729d33141363 OpenGEX 0 403 406 2023-07-15T11:37:41Z Eric Lengyel 1 Redirected page to [[Open Game Engine Exchange]] wikitext text/x-wiki #REDIRECT [[Open Game Engine Exchange]] 1fc3719a2aea97667d992ff767e200d2c77eba7d Movie Importer 0 404 407 2023-07-15T11:38:39Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Movieimporter.png|right|frame|'''Figure 1.''' The Movie Importer dialog.]] The '''Movie Importer''' tool is used to generate movies in the proprietary C4 Engine <code>.mvi</code> format. This functionality is part of the '''Movie Tool''' plugin. To generate a movie, either choose '''Import Movie''' from the [[C4 Menu]] or type the <code>imovie</code> command in the [[Command Console]]. This causes this Import Movie dialog, shown in Figure 1, to be displ..." wikitext text/x-wiki __NOTOC__ [[File:Movieimporter.png|right|frame|'''Figure 1.''' The Movie Importer dialog.]] The '''Movie Importer''' tool is used to generate movies in the proprietary C4 Engine <code>.mvi</code> format. This functionality is part of the '''Movie Tool''' plugin. To generate a movie, either choose '''Import Movie''' from the [[C4 Menu]] or type the <code>imovie</code> command in the [[Command Console]]. This causes this Import Movie dialog, shown in Figure 1, to be displayed. == Source Images == The source images for video frames can be in TGA format or the SEQ format generated when [[Recording Movies|recording movies]] (and these can also be mixed in the same movie). All of the video frames must have the same dimensions, and these dimensions must be a multiple of 8 pixels in both width and height, or an error will occur when trying to generate the movie. Click the '''Add''' button to select source images. The file selection dialog that appears shows files inside the <code>Import</code> folder hierarchy, so this is where source images should be saved prior to generating a movie. Multiple files can be selected at once by holding the shift key or simply typing Ctrl-A to select all files in a directory. You can switch between Targa (TGA) files and Sequence (SEQ) files using the popup menu at the bottom of the selection dialog. Any numbering in source image file names does not need to include extra 0 characters to pad all the numbers out to the same length. When a string of numerical characters is encountered in a file name, it is treated as a single symbol for purposes of sorting the files. The files are displayed in the movie images list in the order in which they will appear in the movie. == Movie Settings == {| {{Table}} {{Tablehead|Setting|Description}} |- {{Tablerow|'''Output resource name'''|Specifies the name of the movie resource that gets generated relative to the <code>Data</code> directory.}} |- {{Tablerow|'''Compression quality level'''|Determines the quality level at which the movie's video frames are compressed. Higher numbers mean better quality, but at the cost of larger movie files.}} |- {{Tablerow|'''Frame rate (frames/s)'''|Specifies the playback frame rate for the movie.}} |- {{Tablerow|'''Maximum consecutive delta frames'''|Specifies the maximum number of delta frames that can occur consecutively before a new key frame is forced. A value of zero means that every frame is a key frame.}} |- {{Tablerow|'''Maximum delta/key frame size ratio (%)'''|Specifies the maximum ratio between the size of a compressed delta frame and a compressed key frame that will be allowed. For any frames that could be delta frames but exceed this limit, a key frame is forced.}} |- {{Tablerow|'''Include alpha channel in video track'''|Indicates that an alpha channel should be generated for the movie. This results in larger movie files and should only be checked if the source frame images actually contain useful alpha information.}} |- {{Tablerow|'''Audio Settings / Input resource name'''|Specifies the name of an audio file relative to the <code>Import</code> directory. If this is left blank, then the movie will not have an audio track. An audio track must be stored as an uncompressed <code>.wav</code> file with 16-bit samples and one or two channels.}} |} == See Also == * [[Movie Player]] * [[Recording Movies]] [[Category:Movies]] 67c8634145a97da068b5f7b08def322c467d0f37 Movie Player 0 405 408 2023-07-15T11:39:21Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Movieplayer.png|right|thumb|800px|'''Figure 1.''' The Movie Player window.]] The '''Movie Player''' is part of the '''Movie Tool''' plugin that ships with the C4 Engine, and it is used to preview movie files in the engine's proprietary <code>.mvi</code> format. == Opening a Movie == The Movie Player is opened by selecting '''Open Movie''' from the [[C4 Menu]], or by typing <code>movie [''name'']</code> in the [[Command Console]]. If the '''Open Movie''..." wikitext text/x-wiki __NOTOC__ [[File:Movieplayer.png|right|thumb|800px|'''Figure 1.''' The Movie Player window.]] The '''Movie Player''' is part of the '''Movie Tool''' plugin that ships with the C4 Engine, and it is used to preview movie files in the engine's proprietary <code>.mvi</code> format. == Opening a Movie == The Movie Player is opened by selecting '''Open Movie''' from the [[C4 Menu]], or by typing <code>movie [''name'']</code> in the [[Command Console]]. If the '''Open Movie''' menu item is selected (or name is omitted from the console command), then a dialog appears to let you select a movie resource. == Movie Player Layout == The Movie Player window has the layout shown in Figure 1. The slider underneath the movie can be used to change the current playback position. The current playback time is displayed underneath the slider on the left, and the total duration of the movie is shown on the right. The movie is played and stopped using the buttons in the lower-left corner. The movie can be set to loop continuously by checking the '''Loop''' box. == See Also == * [[Movie Importer]] * [[Recording Movies]] [[Category:Movies]] b84589f5ab57b41e0203e35a7eee13d40bc1797f Recording Movies 0 406 409 2023-07-15T11:40:28Z Eric Lengyel 1 Created page with "The C4 Engine has the capability to record the video and audio output as you're playing a game or using the tools. Video is saved to a set of "sequence" files that can later be imported as a movie, and audio is saved to a standard wave file. A movie is generated from these files using the [[Movie Importer]] tool. Recording is started by entering the record command in the [[Command Console]] as follows: <code>record ''name'' [-rate ''fps''] [-noaudio] [-novideo]</code>..." wikitext text/x-wiki The C4 Engine has the capability to record the video and audio output as you're playing a game or using the tools. Video is saved to a set of "sequence" files that can later be imported as a movie, and audio is saved to a standard wave file. A movie is generated from these files using the [[Movie Importer]] tool. Recording is started by entering the record command in the [[Command Console]] as follows: <code>record ''name'' [-rate ''fps''] [-noaudio] [-novideo]</code> The ''name'' parameter specifies the base name of the sequence files that are generated, including the path relative to the C4 Engine application. As recording progresses, the engine generates files named <code>''name''1.seq</code>, <code>''name''2.seq</code>, etc., each of which holds many frames of video data. The audio is saved to a single file named <code>''name''.wav</code>. If the <code>-rate</code> parameter is specified, then video frames are captured at a rate of ''fps'' frames per second, up to a maximum of 60. For best results, ''fps'' should evenly divide 36000. If the <code>-rate</code> parameter is omitted, then the default recording rate is 30 frames per second. By default, both video and audio are recorded. If either the <code>-noaudio</code> or <code>-novideo</code> parameters are specified, then audio or video will not be recorded, respectively. Recording is stopped by entering any <code>record</code> command in the Command Console, with parameters or not, while recording is in progress. All parameters to a <code>record</code> command that stops recording are ignored. In order to avoid showing the console in the movie itself, it is usually convenient to bind the record command to a key. For example, the following command binds the recording functionality to the F1 key. <code>bind F1 "record Import/MyMovies/Movie -rate 20"</code> After this command has been entered, the F1 key can be used to start and stop recording at 20 frames per second. == See Also == * [[Movie Importer]] * [[Movie Player]] * <code>[http://c4engine.com/docs/MovieMgr/MovieMgr_StartRecording.html MovieMgr::StartRecording()]</code> function * <code>[http://c4engine.com/docs/MovieMgr/MovieMgr_StopRecording.html MovieMgr::StopRecording()]</code> function [[Category:Movies]] 1ebdcb6b027c3ceea2f6013165e8b0ca6da7565b Sound Importer 0 407 410 2023-07-15T11:41:20Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Soundimporter.png|right|frame|'''Figure 1.''' The Sound Importer window.]] The '''Sound Importer''' is part of the '''Sound Tool''' plugin that ships with the C4 Engine, and it generates sound resources in the engine's proprietary <code>.snd</code> file format. The Sound Importer can be run by choosing '''Import Sound''' from the [[C4 Menu]] or by typing <code>isound [''name'']</code> in the [[Command Console]]. If the '''Import Sound''' menu item is se..." wikitext text/x-wiki __NOTOC__ [[File:Soundimporter.png|right|frame|'''Figure 1.''' The Sound Importer window.]] The '''Sound Importer''' is part of the '''Sound Tool''' plugin that ships with the C4 Engine, and it generates sound resources in the engine's proprietary <code>.snd</code> file format. The Sound Importer can be run by choosing '''Import Sound''' from the [[C4 Menu]] or by typing <code>isound [''name'']</code> in the [[Command Console]]. If the '''Import Sound''' menu item is selected (or name is omitted from the console command), then a dialog appears to let you select one or more files from the Import directory. == Source Files == The files imported by the Sound Importer must be in uncompressed <code>.wav</code> format having either one or two channels (mono or stereo) with 16-bit or 24-bit samples. Any sampling frequency is allowed. == Sound Settings == {| {{Table}} {{Tablehead|Setting|Description}} |- {{Tablerow|'''Compress sound for streaming'''|Specifies that the sound is to be compressed during import. This must be checked for sounds that will be streamed from the disk, and it must not be checked for sounds that will be played from memory.}} |- {{Tablerow|'''Use lossy compression'''|Specifies that lossy compression may be used. This is ignored if the '''Compress sound for streaming''' box is not checked.}} |} == See Also == * [[Sound Player]] [[Category:Sound]] 56b171059dd54b14df39a70e306a8d9cdb77fd01 Sound Player 0 408 411 2023-07-15T11:41:53Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Soundplayer.png|right|frame|'''Figure 1.''' The Sound Player window.]] The '''Sound Player''' is part of the '''Sound Tool''' plugin that ships with the C4 Engine, and it is used to preview sound files in the engine's proprietary <code>.snd</code> format. == Opening a Sound == The Sound Player is opened by selecting '''Open Sound''' from the [[C4 Menu]], or by typing <code>sound [''name'']</code> in the [[Command Console]]. If the '''Open Sound''' menu..." wikitext text/x-wiki __NOTOC__ [[File:Soundplayer.png|right|frame|'''Figure 1.''' The Sound Player window.]] The '''Sound Player''' is part of the '''Sound Tool''' plugin that ships with the C4 Engine, and it is used to preview sound files in the engine's proprietary <code>.snd</code> format. == Opening a Sound == The Sound Player is opened by selecting '''Open Sound''' from the [[C4 Menu]], or by typing <code>sound [''name'']</code> in the [[Command Console]]. If the '''Open Sound''' menu item is selected (or name is omitted from the console command), then a dialog appears to let you select a sound resource. == Sound Player Layout == The Sound Player window has the layout shown in Figure 1. One or two waveforms are displayed depending on whether the sound is mono or stereo. If the sound is streamed, then the contents of the streaming buffer are displayed, and the waveform changes during playback as new data is loaded. The current playback time is displayed underneath the waveform on the left, and the total duration of the sound is shown on the right. The sampling frequency of the sound resource is shown in the lower-right corner. The sound is played and stopped using the buttons in the lower-left corner, and the volume can be controlled with the '''Volume''' slider. The sound can be set to loop continuously by checking the '''Loop''' box. == See Also == * [[Sound Importer]] [[Category:Sound]] 7e2ad9a65a40ff8b165de1d014135742545b9c72 Font Importer 0 409 412 2023-07-15T11:43:17Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Fontimporter.png|right|frame|'''Figure 1.''' The Font Importer window.]] In most types of applications, text is rendered into a 2D drawing context by the operating system using the information stored in OpenType or TrueType font files. However, this method of text rendering is not compatible with hardware-accelerated 3D graphics, and it suffers from inconsistencies among different platforms. In order to render high-quality text in a 3D environment and pr..." wikitext text/x-wiki __NOTOC__ [[File:Fontimporter.png|right|frame|'''Figure 1.''' The Font Importer window.]] In most types of applications, text is rendered into a 2D drawing context by the operating system using the information stored in OpenType or TrueType font files. However, this method of text rendering is not compatible with hardware-accelerated 3D graphics, and it suffers from inconsistencies among different platforms. In order to render high-quality text in a 3D environment and produce exactly the same results on all platforms, the C4 Engine uses its own internal font format. Fonts used by the C4 Engine are stored as font resources having the <code>.fnt</code> extension. A font resource is generated by the Font Importer tool by importing a OpenType or TrueType font having the <code>.ttf</code> extension. The C4 Engine can render text from all planes containing characters currently defined by the Unicode Standard. The engine always stores and processes strings using the UTF-8 encoding to provide full compatibility with ordinary ASCII strings. To generate a font, either select '''Import Font''' from the [[C4 Menu]] or type <code>ifont</code> in the [[Command Console]]. The Font Importer will then display a dialog allowing you to pick a <code>.ttf</code> file from inside the <code>Import</code> folder. Once you have chosen the font that you want to import, the main Font Importer window will appear. The layout of this window is shown in the Figure&nbsp;1. The Font Importer window displays a 16&times;16 grid containing a preview of the available characters within a single 256-entry code page. Only the characters that are present in the font are shown, and only pages having at least one character in the font are accessible. The list on the right side of the window shows the standard names for the Unicode blocks for which the font provides at least one character. == Code Page Navigation == You can navigate among the available code pages by pressing the Page Up and Page Down keys. Unless a setting has the keyboard focus, the Left Arrow and Right Arrow keys also navigate to the previous and next code pages, respectively. Clicking on a code block name in the block list will cause the first page covered by the block to be shown if you are not already viewing a page that intersects the block's Unicode range. == Character Selection == A single character can be selected by clicking on it. A range of characters can be selected by holding in the Shift key while clicking. The selection is always a contiguous range, and the Unicode values for the characters in the selection are shown at the bottom-left corner of the window. If a single character is selected, then the Unicode name for that character is displayed at the bottom of the window. All characters can be selected at once by typing Ctrl-A, and all characters can be deselected by typing Ctrl-Shift-A. When a code block name is clicked in the block list, all of the glyphs in the block are selected. Typing Ctrl-C while characters are selected causes those characters to be copied to the clipboard. == Character Inclusion and Exclusion == Many fonts contain a far greater number of characters than are needed by an application. The Font Importer lets you pick which characters in the font are included in the font resource generated for use by the C4 Engine. A character is rendered in black when it is marked for inclusion in the font resource. Characters that are not to be included are rendered in gray. The currently selected range of characters can be included or excluded by clicking the '''Include''' and '''Exclude''' buttons at the bottom of the window. By default, only Unicode ranges U+0020..U+007E and U+00A0..U+00FF are included, and the rest of the font is excluded. These ranges correspond to the Basic Latin and Latin-1 Supplement code blocks in the Unicode Standard. The Basic Latin block cannot be excluded&mdash;it is always part of the generated font resource. If an attempt is made to render a character that was not imported (or didn't exist in the original font at all), then the missing character symbol is rendered in its place. This is usually a rectangular box. == Import Settings == {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Font&nbsp;Import&nbsp;Options'''}} |- {{Setting|'''Import&nbsp;multicolor&nbsp;data'''|Determines whether multicolor glyph data is imported for the font, when available. If the <code>.ttf</code> file contains multicolor glyphs such as emoji and pictographs, then this is checked by default.}} |- {{Setting|'''Import&nbsp;kerning&nbsp;data'''|Determines whether kerning data is imported for the font, when available. If the <code>.ttf</code> file contains kerning data, then this is checked by default, and it should generally be left enabled unless you have a good reason to turn them off.}} |- {{Setting|'''Import&nbsp;mark&nbsp;positioning&nbsp;data'''|Determines whether mark positioning data is imported for the font, when available. This data is needed to properly place combining diacritical marks when text is laid out.}} |- {{Setting|'''Import&nbsp;sequence&nbsp;replacement&nbsp;data'''|Determines whether sequence replacement data is imported for the font, when available. This includes information about glyph composition and ligatures defined by the <code>.ttf</code> file.}} |- {{Setting|'''Import&nbsp;alternate&nbsp;substitution&nbsp;data'''|Determines whether alternate substitution data is imported for the font, when available. This includes information about all substitution features defined by the <code>.ttf</code> file.}} |- {{HeadingSetting|'''Glyph&nbsp;Rendering&nbsp;Options'''}} |- {{Setting|'''Generate&nbsp;bounding&nbsp;polygons'''|Causes extra geometric data to be generated so that glyphs can be rendered using 3&ndash;6 sided polygons that cover less area than bounding boxes. This can increase performance for text rendered at large sizes when the '''Use bounding polygons''' setting is checked for a particular text widget. Enabling this optimization during the import process has no performance cost at smaller sizes if the optimization is not enabled for a text widget.}} |- {{Setting|'''Polygon&nbsp;max&nbsp;vertex&nbsp;count'''|Specifies the maximum number of vertices generated for a glyph’s bounding polygon, which can be in the range 4&ndash;6. The import process takes longer for higher values.}} |- {{Setting|'''Polygon&nbsp;interior&nbsp;edge&nbsp;cost'''|Specifies the interior edge cost factor for a glyph’s bounding polygon. This has an effect bounding polygons in such a way that interior edge lengths are considered more or less expensive when determining the optimal shape.}} |- {{Setting|'''Generate&nbsp;outline&nbsp;glyph&nbsp;effect'''|Causes expanded outlines to be generated for all glyphs so they can be rendered with the outline effect. Using this option increases file size significantly.}} |- {{Setting|'''Outline&nbsp;effect&nbsp;size&nbsp;(em)'''|Specifies the size of the outline effect in em units. This is typically a very small value near the default of 0.2.}} |- {{Setting|'''Outline&nbsp;effect&nbsp;miter&nbsp;limit'''|Specifies the miter limit for the outline effect. When this limit is exceeded at a corner in a glyph, the corner is rounded or beveled.}} |- {{Setting|'''Outline&nbsp;effect&nbsp;join&nbsp;style'''|Specifies whether corners are rounded or beveled when the miter limit is exceeded.}} |- {{HeadingSetting|'''Text&nbsp;Decoration&nbsp;Options'''}} |- {{Setting|'''Underline size (em)'''|The thickness of the underline stroke in em units. This is initially set to the default value defined in the <code>.ttf</code> file.}} |- {{Setting|'''Underline position (em)'''|The position of the bottom of the underline stroke, in em units. This is initially set to the default value defined in the <code>.ttf</code> file. Negative values are below the baseline.}} |- {{Setting|'''Strikethrough size (em)'''|The thickness of the strikethrough stroke in em units. This is initially set to the default value defined in the <code>.ttf</code> file.}} |- {{Setting|'''Strikethrough position (em)'''|The position of the bottom of the strikethrough stroke, in em units. This is initially set to the default value defined in the <code>.ttf</code> file. Positive values are above the baseline.}} |- {{HeadingSetting|'''Script&nbsp;Transform&nbsp;Options'''}} |- {{Setting|'''Subscript scale X'''|The scale in the ''x'' direction for transform-based subscripts. This is initially set to the default value defined in the <code>.ttf</code> file.}} |- {{Setting|'''Subscript scale Y'''|The scale in the ''y'' direction for transform-based subscripts. This is initially set to the default value defined in the <code>.ttf</code> file.}} |- {{Setting|'''Subscript offset X'''|The offset in the ''x'' direction, in em units, for transform-based subscripts. This is initially set to the default value defined in the <code>.ttf</code> file.}} |- {{Setting|'''Subscript offset Y'''|The offset in the ''y'' direction, in em units, for transform-based subscripts. This is initially set to the default value defined in the <code>.ttf</code> file.}} |- {{Setting|'''Superscript scale X'''|The scale in the ''x'' direction for transform-based superscripts. This is initially set to the default value defined in the <code>.ttf</code> file.}} |- {{Setting|'''Superscript scale Y'''|The scale in the ''y'' direction for transform-based superscripts. This is initially set to the default value defined in the <code>.ttf</code> file.}} |- {{Setting|'''Superscript offset X'''|The offset in the ''x'' direction, in em units, for transform-based superscripts. This is initially set to the default value defined in the <code>.ttf</code> file.}} |- {{Setting|'''Superscript offset Y'''|The offset in the ''y'' direction, in em units, for transform-based superscripts. This is initially set to the default value defined in the <code>.ttf</code> file.}} |} == Saved Configurations == When a font is imported, the ranges of included characters and the import settings are saved in a <code>.cfg</code> in the same folder as the <code>.ttf</code> file being imported. The next time the same font is imported, that information is read from the <code>.cfg</code> file and used to initialize the Font Importer settings. == See Also == * [[Text Widget]] * [[Text Formatting]] * [http://c4engine.com/docs/InterfaceMgr/Font.html <code>Font</code> class]. 00911a71e69ee44883b87bfa40d053db624ea78f Texture Importer 0 410 413 2023-07-15T11:44:42Z Eric Lengyel 1 Created page with "__NOTOC__ Texture maps used by the C4 Engine have the <code>.tex</code> file extension. These texture map resources are created by importing texture images from a subdirectory of the <code>Import</code> directory using the Texture Importer tool. The Texture Importer tool supports <code>.tga</code> files, which may be in 8-bit grayscale, 16-bit color, 24-bit color, or 32-bit color format, with or without RLE compression. When a texture is imported, a <code>.cfg</code> f..." wikitext text/x-wiki __NOTOC__ Texture maps used by the C4 Engine have the <code>.tex</code> file extension. These texture map resources are created by importing texture images from a subdirectory of the <code>Import</code> directory using the Texture Importer tool. The Texture Importer tool supports <code>.tga</code> files, which may be in 8-bit grayscale, 16-bit color, 24-bit color, or 32-bit color format, with or without RLE compression. When a texture is imported, a <code>.cfg</code> file is created in the same folder as the imported texture, and it contains all of the settings that were applied. This file is recognized the next time the texture is imported and used to populate the Import Texture dialog with the settings that were previously used. '''Note:''' All resources imported into the C4 Engine should be placed in a ''subfolder'' of the Import folder, not directly in the Import folder itself. == Texture Maps == [[File:textureimporter.png|right|frame|'''Figure 1.''' The Texture Map Import dialog.]] To import a texture, either choose Import Texture from the [[C4 Menu]] or invoke the <code>itexture</code> [''name''] command in the [[Command Console]]. If the menu command is chosen, or the name is omitted from the console command, then the Texture Importer tool will open an Import Texture dialog that lets you select a <code>.tga</code> file from a subdirectory of the <code>Import</code> directory. After selecting an image file to import, the Import dialog is opened with the default settings shown in the following figure. These default settings are usually appropriate for ordinary color texture maps. === Texture Map Import Settings === {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Texture Format'''}} |- {{Setting|'''Texture&nbsp;type'''|Selects the OpenGL texture target for this texture map. It can be one of the following values. * '''2D''' An ordinary 2D texture whose coordinates lie in the range [0, 1] in both dimensions. The width and height of a 2D texture must be a power of two. * '''Rect''' A rectangle texture whose coordinates lie in the range [0, width] and [0, height]. The width and height do not need to be a power of two. The rectangle texture type should not be used for texture maps that are to be used in a 3D setting because they will adversely affect performance when minified. Rectangle textures are primarily used for things like user interface images that appear in a 2D setting. * '''Cube''' A cube map texture. [[#Cube Maps|See below]]. * '''Array 2D''' A texture containing an array of 2D images.}} |- {{Setting|'''Image&nbsp;format'''|Selects the output pixel format for this texture map. It can be one of the following values. * '''RGBA Color''' The image has four channels: red, green, blue, and alpha. * '''Luminance Alpha''' The image has two channels: grayscale luminance and alpha. * '''Luminance''' The image has one grayscale channel, and the alpha is always interpreted to be the maximum value. * '''Intensity''' The image has one grayscale channel, and the alpha is always interpreted to be equal to the gray value.}} |- {{Setting|'''Alpha&nbsp;channel'''|Specifies what kind of information is stored in the alpha channel of the texture. It can be one of the following values. (If alpha channel information is specified, then the TGA file being imported must use a 32-bit format.) * '''None''' There is no information stored in the alpha channel. * '''Transparency''' The alpha channel contains transparency information. * '''Gloss''' The alpha channel contains a gloss map. Whenever a texture containing a gloss map in the alpha channel is used in a material, any specularity, environment map, or reflection term is modulated by the gloss map. * '''Opacity''' The alpha channel contains an opacity map. Whenever a texture containing an opacity map in the alpha channel is used in a material, the opacity is used to linearly interpolate between the diffuse term and the refraction term. * '''Glow''' The alpha channel contains glow intensity values that are used by the glow post-processing effect. This should only be used for emission maps. * '''Occlusion''' The alpha channel will contain ambient occlusion information. This can be a precomputed channel, or it can be generated when the texture is imported. See the description of the '''Calculate ambient occlusion in alpha''' box below. * '''Parallax''' The alpha channel of the import texture contains a height map from which parallax mapping information should be calculated. This is selected automatically if the '''Generate parallax data''' box is checked. If the alpha channel of a normal map in a material contains parallax information, the parallax mapping is applied during all rendering passes.}} |- {{Setting|'''S&nbsp;wrap&nbsp;mode''' '''T&nbsp;wrap&nbsp;mode'''|Specifies what wrap modes to apply to the texture map. They can each be one of the following values. * '''Repeat''' The texture is addressed using the <code>GL_REPEAT</code> wrap mode. * '''Clamp''' The texture is addressed using the <code>GL_CLAMP_TO_EDGE</code> wrap mode. If this mode is not available, the <code>GL_CLAMP</code> is used instead. * '''Clamp to Border''' The texture is addressed using the <code>GL_CLAMP_TO_BORDER</code> wrap mode. * '''Mirror Repeat''' The texture is addressed using the <code>GL_MIRRORED_REPEAT</code> wrap mode. * '''Mirror Clamp''' The texture is addressed using the <code>GL_MIRROR_CLAMP_TO_EDGE</code> wrap mode. * '''Mirror Clamp to Border''' The texture is addressed using the <code>GL_MIRROR_CLAMP_TO_BORDER</code> wrap mode.}} |- {{Setting|'''Use&nbsp;block&nbsp;compression'''|The output texture is stored in a hardware-recognized compression format. This should be turned on for almost all texture maps for best performance and memory usage. (This setting is ignored if the image format is not RGBA Color, if the width and height of the image are not both multiples of 4, or if generating a normal map with parallax data.)}} |- {{HeadingSetting|'''Texture Flags'''}} |- {{Setting|'''Disable&nbsp;filtering'''|No filtering is applied to this texture map, and point sampling is used instead.}} |- {{Setting|'''Disable&nbsp;anisotropic&nbsp;filtering'''|Anisotropic filtering is disabled for this texture map, but ordinary bilinear or trilinear filtering is still applied.}} |- {{Setting|'''Require&nbsp;high-resolution&nbsp;rendering'''|The texture map is always rendered using the highest resolution available, even if the user has selected a lower-quality option in the Graphics Settings dialog.}} |- {{HeadingSetting|Map/Channel Generation}} |- {{Setting|'''Calculate&nbsp;normal&nbsp;map'''|The import texture is treated as a height map from which a normal map should be calculated. Each height is multiplied by the value specified in the '''Height map scale''' field and used to determine the normal vector at each pixel. In order to access all features of the engine, normal maps should be created by the Texture Importer tool, and not by external programs. You can still use normal maps generated by external tools, but if you do, then you can't have associated parallax maps, horizon maps, or ambient occlusion maps. External normal maps can still be block compressed, but you must check the '''Treat RGB channels as vector''' box.}} |- {{Setting|'''Generate&nbsp;parallax&nbsp;data'''|When checked in addition to '''Calculate normal map''', the height in the alpha channel is converted into special parallax data used by the engine. The same height map must be stored in all four channels of the import texture.}} |- {{Setting|'''Generate&nbsp;horizon&nbsp;maps'''|When checked in addition to '''Calculate normal map''', a separate texture is generated that contains horizon map data. This texture has the same name as the normal map, but with a different suffix. If the name of the normal map ends in <code>-nrml</code>, then this suffix is changed to <code>-hrzn</code>. Otherwise the suffix <code>-h</code> is added to the full name of the normal map (excluding the extension <code>.tex</code>). A horizon map is applied to a material when the '''Enable horizon mapping''' box is checked in the [[Material Editor]].}} |- {{Setting|'''Calculate&nbsp;ambient&nbsp;occlusion&nbsp;in&nbsp;alpha'''|The heights stored in the alpha channel are scaled by the value specified in the '''Height map scale''' field and used to calculate an ambient occlusion factor that is applied in the ambient rendering pass.}} |- {{Setting|'''Height&nbsp;map&nbsp;scale'''|Specifies a scale that is applied to all height values. A scale factor of 1.0 corresponds to the width of a single texel in the import texture.}} |- {{Setting|'''Height&nbsp;map&nbsp;channel'''|Selects a channel to be used as the source of the height map for all calculations.}} |- {{HeadingSetting|'''Options'''}} |- {{Setting|'''Output&nbsp;file&nbsp;name'''|Specifies the name of the texture file that will be created. (It should not include the extension.) This usually does not need to be changed from the default setting.}} |- {{Setting|'''Calculate&nbsp;mipmap&nbsp;levels'''|All mipmap levels for this texture are calculated and stored in the texture resource. Turning this off for textures that are used in a 3D environment can have a negative effect on performance.}} |- {{Setting|'''Bleed&nbsp;colors&nbsp;for&nbsp;alpha&nbsp;test'''|Causes texels that would fail the alpha test to pick up the color of the nearest texel that passes the alpha test. This process helps remove borders that can appear when alpha-tested textures are rendered. When this setting is checked, the alpha values in lower-resolution mipmaps are also boosted to prevent fade-out of alpha-tested geometries.}} |- {{Setting|'''Treat&nbsp;RGB&nbsp;channels&nbsp;as&nbsp;vector'''|Mipmaps are calculated for vector data instead of color data. This is useful if you're importing a precomputed normal map as opposed to calculating a normal map from a height field. This box must be checked in order to get block compression for an externally generated normal map.}} |- {{Setting|'''Invert&nbsp;green&nbsp;channel'''|The green channel of the import texture image is inverted. This is useful for changing handedness in externally generated normal maps.}} |- {{Setting|'''Scale&nbsp;texture&nbsp;to&nbsp;half&nbsp;resolution'''|The import texture image is reduced to half size in each direction before being processed.}} |- {{Setting|'''Scale&nbsp;horizon&nbsp;maps&nbsp;to&nbsp;half&nbsp;resolution'''|The horizon map is generated from an import texture image that has been reduced to half size in each direction. Using this option can usually save a significant amount of memory without a noticeable reduction in rendering quality. (If '''Scale texture to half resolution''' is also checked, then both scales are applied, so the horizon map is only one-quarter the size in each direction.)}} |- {{Setting|'''Flip&nbsp;image&nbsp;vertically'''|The import texture image is flipped in the vertical direction before being processed.}} |- {{HeadingSetting|'''Array Texture'''}} |- {{Setting|'''Cell count'''|When the '''Texture type''' is set to '''Array 2D''', the cell count setting specifies how many layers the array texture has. The layers should be stacked vertically in the input image, and the total height divided by the cell count must be an integer.}} |- {{HeadingSetting|'''Skybox Haze'''}} |- {{Setting|'''Haze&nbsp;color'''|When checked, the haze color is applied at the bottom of the texture image with the appropriate warping for use as a skybox texture.}} |- {{Setting|'''Haze&nbsp;elevation'''|Specifies the relative height to which the haze extends above the horizon. (Ignored if '''Haze color''' is not checked.)}} |- {{HeadingSetting|'''Cursor Data'''}} |- {{Setting|'''Image&nbsp;center&nbsp;X''' '''Image&nbsp;center&nbsp;Y'''|If importing a cursor texture, these settings specify the coordinates, in pixels, where the center, or '''hot spot''', of the cursor is located.}} |} == Cube Maps == A cube map can be imported by creating a single TGA file that contains all six faces of the cube. Each cube face must be square and have a width that is a power of two. The importer supports the four layouts shown in the following table. Each face must have the correct orientation in order for the cube map to work properly, and these are shown in the figures. The ''z'' axis always represents the up direction, and the direction specified in the center of each face represents the axis that points into the image. {| {{Table}} {{Tablehead|Layout|Description}} |- {{Tablerow|[[File:Cube_hcross.png]]|'''Horizontal Cross.''' The image should be exactly 4 faces in width and 3 faces in height.}} |- {{Tablerow|[[File:Cube_vcross.png]]|'''Vertical Cross.''' The image should be exactly 3 faces in width and 4 faces in height.}} |- {{Tablerow|[[File:Cube_hstrip.png]]|'''Horizontal Strip.''' The image should be exactly 6 faces in width and 1 face in height.}} |- {{Tablerow|[[File:Cube_vstrip.png]]|'''Vertical Strip.''' The image should be exactly 1 face in width and 6 faces in height.}} |} == Normal Maps == [[File:normalimporter.png|right|frame|'''Figure 2.''' The Normal Map Import dialog.]] === Normal Map Import Settings === {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Texture Format'''}} |} == See Also == * [[Texture Viewer]] * [[Material Editor]] [[Category:Shaders]] 0bca1d76b560aa0cc7ad8e33706da6a886b9a8d3 Texture Viewer 0 411 414 2023-07-15T11:45:41Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Textureviewer.png|right|frame|'''Figure 1.''' The Texture Viewer window.]] The '''Texture Viewer''' is part of the '''Texture Tool''' plugin that ships with the C4 Engine, and it is used to preview texture files in the engine's proprietary <code>.tex</code> format. == Opening a Texture == The Texture Viewer is opened by selecting '''Open Texture''' from the [[C4 Menu]], or by typing <code>texture [''name'']</code> in the [[Command Console]]. If the '''..." wikitext text/x-wiki __NOTOC__ [[File:Textureviewer.png|right|frame|'''Figure 1.''' The Texture Viewer window.]] The '''Texture Viewer''' is part of the '''Texture Tool''' plugin that ships with the C4 Engine, and it is used to preview texture files in the engine's proprietary <code>.tex</code> format. == Opening a Texture == The Texture Viewer is opened by selecting '''Open Texture''' from the [[C4 Menu]], or by typing <code>texture [''name'']</code> in the [[Command Console]]. If the '''Open Texture''' menu item is selected (or name is omitted from the console command), then a dialog appears to let you select a texture resource. == Texture Viewer Layout == The Texture Viewer window has the layout shown in Figure 1. Information about the texture format is displayed in the upper-right corner. The '''Flip vertically''' box can be checked to invert the texture image in the vertical direction. If the '''Enable alpha blend''' box is checked, then the texture image is rendered with alpha blending. The background color or pattern is set using the '''Background''' popup menu. If the texture has mipmaps, then you can cycle through them by typing Ctrl-M. If the texture has multiple layers, then you can cycle through them by typing Ctrl-D. == See Also == * [[Texture Importer]] * [[Material Editor]] [[Category:Shaders]] 364e0f69f48cb1077d23217b2c31a3d61d04a83f File:Cube hcross.png 6 412 415 2023-07-15T11:46:02Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Cube vcross.png 6 413 416 2023-07-15T11:46:13Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Cube hstrip.png 6 414 417 2023-07-15T11:46:21Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Cube vstrip.png 6 415 418 2023-07-15T11:46:29Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Model Viewer 0 416 419 2023-07-15T11:47:19Z Eric Lengyel 1 Created page with "__NOTOC__ The '''Model Viewer''' is a plugin tool for the C4 Engine. It is used to preview dynamic models and to import animations for those models. == Opening a Model == The Model Viewer is opened by selecting Open Model from the [[C4 Menu]], or by typing <code>model</code> [''name''] in the [[Command Console]]. If the Open Model menu item is selected (or ''name'' is omitted from the console command), then a dialog appears to let you select a model resource. == Model..." wikitext text/x-wiki __NOTOC__ The '''Model Viewer''' is a plugin tool for the C4 Engine. It is used to preview dynamic models and to import animations for those models. == Opening a Model == The Model Viewer is opened by selecting Open Model from the [[C4 Menu]], or by typing <code>model</code> [''name''] in the [[Command Console]]. If the Open Model menu item is selected (or ''name'' is omitted from the console command), then a dialog appears to let you select a model resource. == Model Viewer Layout == [[File:Modelviewer.png|right|frame|'''Figure 1.''' The Model Viewer window.]] The Model Viewer window has the layout shown in Figure 1. == Tool Buttons == {| {{Table}} {{Tablehead3|Icon|Shortcut|Function}} |- {{Tablerow3|[[File:Tool_orbit.png]]|1 or Alt with the Light tool|'''Orbit Model'''. Orbits about the center of the model.}} |- {{Tablerow3|[[File:Tool_light.png]]|2 or Alt with the Orbit tool|'''Move Light'''. Moves the light source about the center of the model.}} |- {{Tablerow3|[[File:Tool_scroll.png]]|6 or Alt key with any tool|'''Scroll Viewport'''. Dragging with this tool pans the viewport.}} |- {{Tablerow3|[[File:Tool_zoom.png]]|7 or Mouse Wheel with any tool|'''Zoom Viewport'''. Dragging vertically with this tool zooms in and out of the viewport.}} |- {{Tablerow3|[[File:Tool_camera.png]]|9 or Right Mouse Button with any tool|'''Free Camera Move'''. When the mouse button is held down with this tool, the WSAD keys can be used to fly the camera around forward, backward, left, and right. The Space and C keys move up and down.}} |} == Animation == The animation list shows the animation resources that exist in the same directory as the model resource. A model resource and its associated animations are typically grouped into their own subfolder somewhere within the <code>Data</code> directory. Animation resources have the extension <code>.anm</code>. Selecting an animation from the list causes that animation to be activated. The animation can then be played using the controls at the top of the Animation page. The slider below the viewport shows what frame of the animation is currently being displayed. It can be dragged to move the model into the pose for any available frame, and it moves automatically when an animation is being played. The two circular markers below the slider can be dragged to limit the animation to a specific range of frames. The Loop, Oscillate, and Reverse check boxes control how the animation is looped and in what direction the animation is played. == Importing Animations == [[File:Importanimation.png|right|frame|'''Figure 2.''' The Import Animation dialog.]] A new animation can be imported by clicking the Import button below the animation list. A dialog box then shows the animations that are available for import in the subfolder of the <code>Import</code> directory corresponding to the model's location in the <code>Data</code> directory. For example, if the model resource is in the <code>Data/MyGame/MyMonster/</code> folder, then the animations would be imported from the <code>Import/MyGame/MyMonster/</code> folder. The Import Animation dialog has the appearance shown in Figure 2. When an animation is imported, differences between the up direction in the source application and in the C4 Engine are automatically resolved. You do not need to worry about the fact that your models may have been created in a setting where the ''y'' axis points up. (In the engine, the ''z'' axis points up.) There are some options at the bottom of the import dialog that can be used to modify the transforms applied to the root node of the model when the animation is imported. {| {{Table}} {{Tablehead|Option|Description}} |- {{Tablerow|'''Anchor x-y to origin'''|Forces the model to stay at the origin in the horizontal plane, but it is still free to move up and down.}} |- {{Tablerow|'''Anchor z to origin'''|Forces the model to stay at the origin in the vertical direction.}} |- {{Tablerow|'''Freeze root node position'''|Forces the root node of the model to stay at its current position, as shown in the model viewer.}} |- {{Tablerow|'''Preserve missing node transforms'''|Preserves the current transforms, as shown in the model viewer, for any nodes not present in the imported animation file instead of resetting them to the identity.}} |- {{Tablerow|'''Rotate root node'''|Can be used to apply a 90-degree or 180-degree rotation to the model about the vertical axis. This can be useful if the model is not facing the right direction.}} |} == Display == In the Display page, the '''Detail level bias''' slider allows you increase or decrease the detail level for the model so that different LOD meshes can be seen, if present. The check boxes can be used to display the information described in the following table. {| {{Table}} {{Tablehead|Option|Description}} |- {{Tablerow|'''Turn off light'''|Turns off the light source that the model viewer adds to the scene.}} |- {{Tablerow|'''Show wireframe'''|Shows the triangles as a wireframe overlay.}} |- {{Tablerow|'''Show normals'''|Shows the normal vectors for all vertices.}} |- {{Tablerow|'''Show tangents'''|Shows the tangent vectors for all vertices.}} |- {{Tablerow|'''Show skeleton'''|Shows the bones for the model's skeleton (if present).}} |- {{Tablerow|'''Freeze motion blur'''|Freezes the motion blur for the model when the animation is stopped.}} |} 4fa9ef9fe198014ddd4d4f1cc8c111932abd1300 Landscaping Editor 0 417 420 2023-07-15T11:48:09Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Landscapingeditor.png|right|frame|'''Figure 1.''' The Landscaping Editor window.]] The '''Landscaping Editor''' is a tool inside the [[World Editor]] that is used to create landscaping paint brushes. The Landscaping Editor is opened by double-clicking on an existing paint brush in the [[Landscaping Page]] or by choosing '''New Landscaping Brush...''' from the menu in the Landscaping Page. == See Also == * [[Landscaping Page]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Landscapingeditor.png|right|frame|'''Figure 1.''' The Landscaping Editor window.]] The '''Landscaping Editor''' is a tool inside the [[World Editor]] that is used to create landscaping paint brushes. The Landscaping Editor is opened by double-clicking on an existing paint brush in the [[Landscaping Page]] or by choosing '''New Landscaping Brush...''' from the menu in the Landscaping Page. == See Also == * [[Landscaping Page]] [[Category:Editor]] 8bb5a2180155e497a302266439bf81fadb62e068 World Editor 0 418 421 2023-07-15T11:49:54Z Eric Lengyel 1 Created page with "The '''World Editor''' tool module is used to create every scene that the C4 Engine displays (however, scene data may be imported from other sources.) All of the data describing a world is stored in a world resource having the <code>.wld</code> extension, and world resources are stored in subfolders of the <code>Data</code> directory. The World Editor is opened by selecting '''New World''' or '''Open World''' from the [[C4 Menu]], or by typing <code>world</code> [''name..." wikitext text/x-wiki The '''World Editor''' tool module is used to create every scene that the C4 Engine displays (however, scene data may be imported from other sources.) All of the data describing a world is stored in a world resource having the <code>.wld</code> extension, and world resources are stored in subfolders of the <code>Data</code> directory. The World Editor is opened by selecting '''New World''' or '''Open World''' from the [[C4 Menu]], or by typing <code>world</code> [''name''] in the [[Command Console]]. If the '''Open World''' menu item is selected (or ''name'' is omitted from the console command), then a dialog appears to let you select a world resource. You can also start the World Editor by using the shortcut Ctrl-O to open a world or the shortcut Ctrl-N to create a new world while any GUI window is open. == Editor Layout == The World Editor has the layout shown below. Most of the window is occupied by one to four viewports that display the world being edited. Across the top of the World Editor are a number of icon buttons that have various functions. Along the left side of the World Editor are a set of &ldquo;tool pages&rdquo; that hold various groups of related tools used for a large variety of tasks such as creating geometries and applying physics. The tool pages are organized into five groups corresponding to broad types of functionality. See [[World Editor Pages]] for more information about these tools. [[File:Worldeditor.png|1200px]] == Tool Buttons == {| {{Table}} {{Tablehead3|Icon|Shortcut|Function}} |- {{Tablerow3|[[File:Tool_boxselect.png]]|0|'''Box Select Tool'''. Selects all nodes that intersect the rectangle that is dragged out.}} |- {{Tablerow3|[[File:Tool_select.png]]|1|'''Select Tool'''. Selects the ''one'' node that is clicked on. The Shift key can be used to add to or subtract from the current selection. This tool can be used to safely select items without the possibility of accidentally moving them.}} |- {{Tablerow3|[[File:Tool_move.png]]|2|'''Move Tool'''. Works just like the Select Nodes tool, except that dragging the cursor moves the selected nodes.}} |- {{Tablerow3|[[File:Tool_rotate.png]]|3|'''Rotate Tool'''. Works just like the Select Nodes tool except that handles appear on selected nodes. Dragging a handle rotates the selected nodes. The Shift key can be used while rotating to enable angle snap.}} |- {{Tablerow3|[[File:Tool_resize.png]]|4|'''Resize Tool'''. Works just like the Select Nodes tool except that handles appear on selected nodes. Dragging a handle resizes the selected nodes.}} |- {{Tablerow3|[[File:Tool_connect.png]]|5|'''Connect Tool'''. Works just like the Select Nodes tool except that connectors appear on selected nodes (if they have any).}} |- {{Tablerow3|[[File:Tool_surface.png]]|6|'''Select Surface Tool'''. Selects individual surfaces of geometry nodes.}} |- {{Tablerow3|[[File:Tool_scroll.png]]|Alt key with any tool|'''Scroll Tool'''. Dragging with this tool pans the viewport.}} |- {{Tablerow3|[[File:Tool_zoom.png]]|Mouse Wheel with any tool|'''Zoom Tool'''. Dragging vertically with this tool zooms in and out of a viewport.}} |- {{Tablerow3|[[File:Tool_boxzoom.png]]||'''Box Zoom Tool'''. A viewport is zoomed to the rectangle dragged out by this tool.}} |- {{Tablerow3|[[File:Tool_orbit.png]]|8 or Control key with any tool|'''Orbit Tool'''. (This tool can only be used in perspective viewports.) This tool orbits the camera about the selected node that currently has the gizmo. Hold in the Shift key to restrict the camera motion to a horizontal plane. If there is no selected, then the center of the orbit is the world-space origin.}} |- {{Tablerow3|[[File:Tool_camera.png]]|9 or Right Mouse Button with any tool|'''Camera Tool'''. (This tool can only be used in perspective viewports.) When the mouse button is held down with this tool, the WSAD keys can be used to fly the camera around forward, backward, left, and right. The Space and C keys move up and down.}} |} == Toggle Buttons == The toggle buttons all have corresponding items in the '''Layout''' menu. {| {{Table}} {{Tablehead|Icon|Function}} |- {{Tablerow|[[File:Flag_backfaces.png]]|'''Toggle Backfaces'''. Shows or hides backfaces for geometries in wireframe display.}} |- {{Tablerow|[[File:Flag_worlds.png]]|'''Toggle Referenced Worlds'''. Shows or hides worlds that are externally referenced by marker nodes.}} |- {{Tablerow|[[File:Flag_models.png]]|'''Toggle Models'''. Shows or hides nodes that are part of external model resources.}} |- {{Tablerow|[[File:Tool_light.png]]|'''Toggle Lighting'''. When active, full lighting is rendered in perspective viewports.}} |- {{Tablerow|[[File:Flag_center.png]]|'''Draw from Center'''. When active, many tools operate in relation to the center of a node instead of the opposite corner.}} |- {{Tablerow|[[File:Flag_cap.png]]|'''Cap Geometry'''. When active, new geometries include end caps. When inactive, only lateral surfaces are created (e.g., for a cylinder).}} |} == Viewports == The World Editor displays one to four viewports at a time, but manages eight separate viewports internally. The visual configuration of the viewports can be changed using the buttons in the [[Viewports Page]]. The eight viewports are the four quarter-size viewports and the four half-size viewports (two horizontal and two vertical) of which at most four are shown in any multi-viewport configuration. Any viewport can be shown by itself at full size by typing Ctrl-''n'' (or Cmd-''n'' on the Mac), where ''n'' is a number between 1 and 8, or by selecting it from the Layout menu. Typing Ctrl-''n'' again when viewport ''n'' is shown at full size returns to the previous multi-viewport configuration. There are three types of viewports: orthographic, perspective, and scene graph. Orthographic viewports can display the scene from one of six directions corresponding to the positive and negative ''x'', ''y'', and ''z'' axes. The type of each viewport can be changed by right-clicking in a viewport (or Ctrl-clicking on the Mac) and selecting a new viewport type from the popup menu that appears. The scene graph viewport is a special viewport that displays the scene hierarchy. All of the nodes in the scene are displayed in a tree that represents the actual structure of the scene. Subtrees can be collapsed or expanded by clicking on the collapse boxes between the various levels of the hierarchy. In a scene graph viewport, the Select and Move tool provides the capability to reparent nodes. The currently selected nodes can be reparented by dragging them to another node that will serve as the new parent. (Nodes cannot be reparented to any of their descendants.) == Current Target Zone == Worlds are divided into sections called ''zones'', and zones are connected by ''portals''. Zones can be hierarchically organized, and the root node of every world is an <code>InfiniteZone</code> node. Zones are displayed in the World Editor with a black and yellow cross-hatched boundary. It's important to understand that whenever a new node is placed in the world, it gets added to the ''current target zone''. The target zone is set by selecting a zone and choosing Set Target Zone from the Node menu (or using the shortcut Ctrl-T). The current target zone is displayed with a green boundary instead of yellow. At any time, nodes can be moved into the current target zone by selecting them and choosing Move to Target Zone from the Node menu (or using the shortcut Ctrl-Shift-T) or by dragging them to the target zone in the scene graph viewport. Most of the time, you want to place new nodes in the infinite zone. The infinite zone can be made the current target zone by choosing Set Infinite Target Zone from the Node menu, which has the shortcut Ctrl-Y. == Gizmo == The ''gizmo'' is a control that appears for one of the selected nodes. It shows the orientation of the node's local axes in red, green, and blue for the ''x'', ''y'', and ''z'' directions, respectively. When the Select and Move tool is in use, the arrowheads on the axes can be dragged in any viewport to move the node along the corresponding direction. Boxes also appear where the gizmo axes cross, and dragging these causes the node to be moved in a plane. When the Select and Rotate tool is in use, circular arcs appear between the gizmo's axes, and dragging along these causes the node to be rotated in a plane. The gizmo assignment can be iterated through the nodes in the current selection by pressing the Tab key. Typing Shift-Tab iterates through the selected nodes in the reverse order. == Menu Commands == === World Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Close'''|Ctrl-W|Closes the current editor window.}} |- {{Tablerow3|'''Save World'''|Ctrl-S|Saves the current world.}} |- {{Tablerow3|'''Save World As...'''|Ctrl-Shift-S|Saves the current world after prompting for a file name.}} |- {{Tablerow3|'''Save and Play World'''|Ctrl-P|Saves the current world, closes the World Editor, and loads the world in the game. You can return to the world you were editing by hitting escape (to bring up the main menu) or tilde (to open the [[Command Console]]) and then pressing Ctrl-Shift-P.}} |- {{Tablerow3|'''Import Scene...'''||Imports a scene from an external format. The stock engine includes importers that can read [[OpenGEX]] and Collada files.}} |- {{Tablerow3|'''Export Scene...'''||Exports the current world to an external format using an export plugin. There are no exporters in the stock engine, so this item is disabled by default.}} |- {{Tablerow3|'''Load from Model Resource...'''||Loads a model from the engine's <code>MDL</code> format and places it in the world. This should be used to import nodes from an <code>MDL</code> file so that they can be edited only when the original world from which the model was exported is no longer available. This command is not intended to be used as part of routine workflow. To place models in a world as game objects, use the [[Models Page]].}} |- {{Tablerow3|'''Save to Model Resource...'''||Saves the current world in the engine's <code>MDL</code> format. This is intended to be a one-way process, and all editor-specific information about the world will be stripped out in the process. If you expect to edit the model again, then you should also save a copy as an ordinary world (<code>WLD</code>) file.}} |} === Edit Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Undo'''|Ctrl-Z|Undoes the last action. (Supports multiple undo.)}} |- {{Tablerow3|'''Cut'''|Ctrl-X|Cuts the current selection to the clipboard.}} |- {{Tablerow3|'''Copy'''|Ctrl-C|Copies the current selection to the clipboard.}} |- {{Tablerow3|'''Paste'''|Ctrl-V|Pastes the contents of the clipboard to the world. Note that the clipboard is erased whenever all worlds are closed, so to copy from one world and paste into another, leave the source world open until you've pasted in the destination world.}} |- {{Tablerow3|'''Clear'''|Delete|Deletes the current selection.}} |- {{Tablerow3|'''Select All'''|Ctrl-A|Selects every node in the current world.}} |- {{Tablerow3|'''Unselect All'''|Ctrl-Shift-A|Unselects everything that is currently selected.}} |- {{Tablerow3|'''Select All in Zone'''||Selects every node that is visible in the currently selected zone.}} |- {{Tablerow3|'''Select Super Node'''|Ctrl-Up&nbsp;arrow|Selects the parents of the currently selected nodes.}} |- {{Tablerow3|'''Select Subtree'''|Ctrl-Down&nbsp;arrow|Selects all of the descendants for the currently selected nodes.}} |- {{Tablerow3|'''Lock Selection'''|Ctrl-K|Locks the current selection so that it cannot be changed. When the selection is locked, a small lock icon appears next to the cursor.}} |- {{Tablerow3|'''Unlock Selection'''|Ctrl-Shift-K|Unlocks the current selection.}} |- {{Tablerow3|'''Duplicate'''|Ctrl-D|Duplicates the current selection.}} |- {{Tablerow3|'''Clone'''|Ctrl-Shift-D|Duplicates the current selection, but creates references to their object data instead of duplicating it.}} |} === Node Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Get Info...'''|Ctrl-I|Opens the Get Info dialog for the selected nodes.}} |- {{Tablerow3|'''Edit Script or Panel'''|Ctrl-E|Opens the [[Script Editor]] if a single node is selected and has a Script Controller attached to it, or opens the [[Panel Editor]] if a single panel effect is selected.}} |- {{Tablerow3|'''Group Nodes'''|Ctrl-G|Creates a group node and makes it the parent of the current selection.}} |- {{Tablerow3|'''Reset Transform to Identity'''||Resets the transform for each of the selected nodes to the identity matrix.}} |- {{Tablerow3|'''Reset Rotation to Identity'''||Resets the rotation portion of the transform for each of the selected nodes to the identity matrix without affecting their positions.}} |- {{Tablerow3|'''Align Position to Grid'''||Moves each of the selected nodes so that it is aligned to the grid.}} |- {{Tablerow3|'''Set Target Zone'''|Ctrl-T|Makes the currently selected zone the target zone. (Only available if one zone is selected.)}} |- {{Tablerow3|'''Set Infinite Target Zone'''|Ctrl-Y|Makes the infinite root zone the target zone.}} |- {{Tablerow3|'''Move to Target Zone'''|Ctrl-Shift-T|Moves (reparents) the currently selected nodes into the target zone.}} |- {{Tablerow3|'''Connect Node'''|Ctrl-L|Connects the currently selected connector to the currently selected node.}} |- {{Tablerow3|'''Unconnect Node'''|Ctrl-U|Unconnects the currently selected connector.}} |- {{Tablerow3|'''Connect to Infinite Zone'''||Connects the current selected portals to the infinite root zone.}} |- {{Tablerow3|'''Select Connected Node'''||If any connectors are selected, this selects the nodes that they are connected to.}} |- {{Tablerow3|'''Select Incoming Connected Nodes'''||Selects all nodes that are connected to the currently selected nodes.}} |- {{Tablerow3|'''Move Viewport Camera to Node||Moves the cameras for all Perspective viewports to the position of the selected node and points them in the direction of the node's ''z'' axis.}} |- {{Tablerow3|'''Open Instanced World'''|Ctrl-Shift-O|If any instanced worlds are selected, this opens their world files in separate world editors.}} |} === Geometry Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Rebuild Geometry'''|Ctrl-R|Rebuilds each selected geometry.}} |- {{Tablerow3|'''Rebuild with New Path'''|Ctrl-Shift-R|Each selected path-based geometry or effect is rebuilt using the path that they are connected to.}} |- {{Tablerow3|'''Recalculate Normals'''||Recalculates normals and tangents for each selected geometry.}} |- {{Tablerow3|'''Bake Transform info Vertices'''|Ctrl-Shift-B|The transform of each selected geometry is baked into its vertices, and the transform is then set to the identity.}} |- {{Tablerow3|'''Reposition Mesh Origin'''||Moves the origin of the selected mesh geometries to the min, max, or center position along each axis, as specified in the dialog that appears.}} |- {{Tablerow3|'''Set Material'''|Ctrl-M|Changes the material for each of the selected nodes to the current material.}} |- {{Tablerow3|'''Remove Material'''||Removes the material from each of the selected nodes.}} |- {{Tablerow3|'''Combine Detail Levels'''||Combines multiple geometries into a single geometry with multiple detail levels.}} |- {{Tablerow3|'''Separate Detail Levels'''||Separates a geometry with multiple levels of detail into multiple geometries with a single level of detail.}} |- {{Tablerow3|'''Convert to Generic Geometry'''|Ctrl-Shift-C|Converts each of the selected geometries to generic mesh geometries.}} |- {{Tablerow3|'''Merge Geometry'''|Ctrl-Shift-M|Merges all of the selected geometries into a single mesh geometry.}} |- {{Tablerow3|'''Invert Geometry'''|Ctrl-Shift-I|Inverts the faces of each of the selected geometries.}} |- {{Tablerow3|'''Intersect Geometry'''|Ctrl-Shift-J|Performs a boolean intersection of the selected geometries and produces a new mesh geometry. (Only available when exactly two geometries are selected.)}} |- {{Tablerow3|'''Union Geometry'''|Ctrl-Shift-U|Performs a boolean union of the selected geometries and produces a new mesh geometry. (Only available when exactly two geometries are selected.)}} |- {{Tablerow3|'''Generate Ambient Occlusion Data'''||Generates per-vertex ambient occlusion data for each selected geometry. This data can be used by the geometries' materials.}} |- {{Tablerow3|'''Remove Ambient Occlusion Data'''||Removes any previously-generated ambient occlusion data from each selected geometry.}} |} == See Also == * [[World Editor Pages]] [[Category:Editor]] 83a20820b785e052ba0c7e9a57318bcfcbc6149c World Editor Pages 0 419 422 2023-07-15T11:50:36Z Eric Lengyel 1 Created page with "A '''page''' is one of the palette-like subwindows shown on the left side of the [[World Editor]]. They are organized into five groups under the tabs '''Object''', '''Material''', '''Earth''', '''Instance''', and '''Editor'''. The pages can be rearranged by dragging them upward and downward by their title bars, and they can be collapsed or expanded by clicking on the small box with a plus or minus symbol in it. Each page contains a group of related tools or settings. Th..." wikitext text/x-wiki A '''page''' is one of the palette-like subwindows shown on the left side of the [[World Editor]]. They are organized into five groups under the tabs '''Object''', '''Material''', '''Earth''', '''Instance''', and '''Editor'''. The pages can be rearranged by dragging them upward and downward by their title bars, and they can be collapsed or expanded by clicking on the small box with a plus or minus symbol in it. Each page contains a group of related tools or settings. The following table describes the individual pages that are currently available in the World Editor, in alphabetical order. {| {{Table}} {{Tablehead|Page|Description}} |- {{Tablerow|[[File:Editor_atmosphere.png]]|'''[[Atmosphere Page | Atmosphere]]'''. The tools in this page are used to place a skybox node or fog space in the scene. See also [[Skyboxes]] and [[Fog Spaces]].}} |- {{Tablerow|[[File:Editor_effects.png]]|'''[[Effects Page | Effects]]'''. The tools in this page are used to place various special effects in the scene. This includes in-game interface panels and frustum cameras that can be rendered inside them.}} |- {{Tablerow|[[File:Editor_find.png]]|'''[[Find Page | Find]]'''. This page contains controls for finding nodes in the scene.}} |- {{Tablerow|[[File:Editor_geometries.png]]|'''[[Geometries Page | Geometries]]'''. The tools in this page are used to place primitive geometries in the scene.}} |- {{Tablerow|[[File:Editor_grid.png]]|'''[[Grid Page | Grid]]'''. This page contains controls for grid settings.}} |- {{Tablerow|[[File:Editor_impostors.png]]|'''[[Impostors]]'''. The single tool in this page places an impostor node in the scene.}} |- {{Tablerow|[[File:Editor_info.png]]|'''[[Info Page | Info]]'''. This page displays information about the node to which the gizmo is currently assigned.}} |- {{Tablerow|[[File:Editor_landscaping.png]]|'''[[Landscaping Page | Landscaping]]'''. This page contains tools for managing landscaping paint brushes and using them to populate a world with vegetation.}} |- {{Tablerow|[[File:Editor_lights.png]]|'''[[Lights Page | Lights]]'''. The tools in this page are used to place light sources in the scene. See [[Lights and Shadows]] for an explanation of how different light types work. See also [[Shadow Spaces]].}} |- {{Tablerow|[[File:Editor_markers.png]]|'''[[Markers Page | Markers]]'''. The tools in this page are used to place marker nodes in the scene.}} |- {{Tablerow|[[File:Editor_material.png]]|'''[[Material Page | Material]]'''. This page displays a table of available materials and contains tools for managing them. The [[Material Editor]] is opened by double-clicking on a material shown in this page.}} |- {{Tablerow|[[File:Editor_models.png]]|'''[[Models Page | Models]]'''. This page shows a list of registered model types. An model can be placed in the scene by selecting one from the list and then clicking in a viewport at the location where you want to place it.}} |- {{Tablerow|[[File:Editor_nodemanagement.png]]|'''[[Node Management Page | Node Management]]'''. This page contains controls for showing, hiding, and selecting nodes based on their types. It also provides masking functionality that controls what types of nodes can be selected by clicking on them in the editor viewports.}} |- {{Tablerow|[[File:Editor_paint.png]]|'''[[Paint Page | Paint]]'''. This page contains tools for drawing in paint spaces.}} |- {{Tablerow|[[File:Editor_particles.png]]|'''[[Particles Page | Particles]]'''. This page contains tools for placing emitters in the scene. It also shows a list of registered particle system types. A particle system can be placed in the scene by selecting one from the list and then clicking in a viewport at the location where you want to place it.}} |- {{Tablerow|[[File:Editor_paths.png]]|'''[[Paths Page | Paths]]'''. This page contains tools for drawing paths. Paths can be composed of linear, elliptical, and Bézier components.}} |- {{Tablerow|[[File:Editor_physics.png]]|'''[[Physics Page | Physics]]'''. This page contains tools for placing physics shapes and joints in the scene.}} |- {{Tablerow|[[File:Editor_placement.png]]|'''[[Placement Page | Placement]]'''. This page contains settings for placement adjustments that can be applied when an instanced world is added to the main world.}} |- {{Tablerow|[[File:Editor_portals.png]]|'''[[Portals Page | Portals]]'''. This page contains tools for placing portals in the scene. It also contains tools for inserting and removing vertices from portals.}} |- {{Tablerow|[[File:Editor_sources.png]]|'''[[Sources Page | Sources]]'''. The tools in this page are used to place sound sources in the scene.}} |- {{Tablerow|[[File:Editor_terrain.png]]|'''[[Terrain]]'''. This page contains all of the tools related to the creation and editing of terrain.}} |- {{Tablerow|[[File:Editor_texturemapping.png]]|'''[[Texture Mapping Page | Texture Mapping]]'''. This page contains tools for offsetting, rotating, and scaling texture coordinates. It also lets you change texcoord generation parameters for individual surfaces numerically.}} |- {{Tablerow|[[File:Editor_transform.png]]|'''[[Transform Page | Transform]]'''. This page lets you change the position, rotation, and size of a node numerically. The transform is shown for the node to which the gizmo is currently assigned.}} |- {{Tablerow|[[File:Editor_triggers.png]]|'''[[Triggers]]'''. The tools in this page are used to place trigger volumes in the scene.}} |- {{Tablerow|[[File:Editor_viewports.png]]|'''[[Viewports Page | Viewports]]'''. This page contains buttons that change the viewport layout. There is also a slider that controls the speed of the perspective viewport camera.}} |- {{Tablerow|[[File:Editor_water.png]]|'''[[Water Page | Water]]'''. This page contains tools related to creating dynamic water surfaces.}} |- {{Tablerow|[[File:Editor_worlds.png]]|'''[[Worlds Page | Worlds]]'''. This page shows a list of instanced worlds used by the current world and contains commands for managing them.}} |- {{Tablerow|[[File:Editor_zones.png]]|'''[[Zones Page | Zones]]'''. The tools in this page are used to place zones in the scene. It also contains tools for inserting and removing vertices from polygon zones.}} |} == See Also == * [[World Editor]] [[Category:Editor]] 8e80d969fd401ed4f1e72816231707b6255ff9d4 File:Pane connectors.png 6 420 423 2023-07-15T11:51:55Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Connectors 0 421 424 2023-07-15T11:51:59Z Eric Lengyel 1 Created page with "[[Image:Pane_connectors.png|right|frame|'''Figure 1.''' Connectors can be added or removed from a node under the '''Connectors''' tab in the '''Node Info''' window.]] Every node in a world can have one or more ''connectors'' attached to it. A connector forms a link between the node that owns it and some other node in the world. Connectors are used for a variety of different purposes, such as connecting a portal to the zone that it leads to or connecting a node with a scr..." wikitext text/x-wiki [[Image:Pane_connectors.png|right|frame|'''Figure 1.''' Connectors can be added or removed from a node under the '''Connectors''' tab in the '''Node Info''' window.]] Every node in a world can have one or more ''connectors'' attached to it. A connector forms a link between the node that owns it and some other node in the world. Connectors are used for a variety of different purposes, such as connecting a portal to the zone that it leads to or connecting a node with a script controller to other nodes that the script operates on. == Creating Connectors == Connectors are added to (or removed from) a node under the '''Connectors''' tab in the '''Node Info''' window (shown in Figure 1). Each connector has a name of up to 15 bytes in length that is used to identify it. This identifier is displayed in the [[World Editor]] and the [[Script Editor]] to distinguish among different connectors attached to a node. To add a new connector to a node, simply click the '''New''' button and type in an identifier for the new entry that appears in the list of connectors. == Built-in Connectors == Some node types have built-in connectors that can activated under the '''Connectors''' tab of the '''Node Info''' window. As shown in Figure 1, a list of built-in connectors is displayed on the left side of the window (empty in this case). Selecting an available built-in connector and clicking on the '''Assign''' button causes the connector to appear in the assigned list. Connectors in the assigned list will show up in the editor as connector boxes that can be linked to other nodes. The names of built-in connectors always begin with a percent character (%). The following table describes the built-in connectors for each type of node that defines them. {| {{Table}} {{Tablehead3|Node Type|Connector|Usage}} |- {{Tablerow3|Zone|<code>%Fog</code>|Connected to a [[Fog Spaces | fog space]] to indicate that a particular fog space should be used in the zone.}} |- {{Tablerow3|Zone|<code>%Acoustics</code>|Connected to an acoustics space to define the acoustical properties of the zone.}} |- {{Tablerow3|Zone|<code>%Illuminance</code>|Connected to an illuminance space to indicate that a particular illuminance space should be applied to geometries in the zone.}} |- {{Tablerow3|Portal|<code>%Zone</code>|Connected to a zone to specify the destination of the portal. This connector is assigned by default when a new portal is created.}} |- {{Tablerow3|Light|<code>%Shadow</code>|Connected to a [[Shadow Spaces | shadow space]] to specify the maximum bounds of shadows cast by the light.}} |- {{Tablerow3|Particle System|<code>%Emitter</code>|Connected to an emitter for use by the particle system.}} |- {{Tablerow3|Physics Node|<code>%Physics</code>|Connected to a physics space defining the boundary of the physics simulation.}} |- {{Tablerow3|Joint|<code>%Body1</code>, <code>%Body2</code>|Connected to nodes that are constrained through the physics joint.}} |- {{Tablerow3|Cloth Geometry|<code>%Wind</code>|Connected to a field with a wind force assigned to it to indicate that the wind should affect the cloth simulation.}} |- {{Tablerow3|Geometry|<code>%Paint</code>|Connected to a [[Paint Spaces | paint space]] to indicate that the geometry's material should use a particular paint texture. This connector is automatically created when a geometry is associated with a paint space using the command in the [[Paint Page]], so it wouldn't normally need to be added manually.}} |- {{Tablerow3|Path Primitive, Tube Effect|<code>%Path</code>|Connected to the path that defines the shape of the geometry or effect.}} |- {{Tablerow3|Instance|<code>%Shadow</code>|Connected to a [[Shadow Spaces | shadow space]] so that a light inside an instanced world can use a shadow space in the instancing world. The light must have the "Use shadow space in instancing world" box checked.}} |- {{Tablerow3|Instance|<code>%Paint</code>|Connected to a [[Paint Spaces | paint space]] so that a geometry inside an instanced world can use a paint space in the instancing world. The geometry must have the "Use paint space in instancing world" box checked.}} |} [[Image:Connectors.png|right|frame|'''Figure 2.''' When the '''Connect Tool''' is selected in the [[World Editor]], the connectors belonging to the selected node are displayed in a list beneath the node in all of the orthographic viewports. This screenshot shows a list of connectors belonging to a trigger node.]] == Connecting to Other Nodes == Each connector can be either unconnected or connected to one node. To specify the target of a connector in the [[World Editor]], click on the '''Connect Tool''' (or press 5) and then select a node for which you want to set an outgoing connection (but don't select the target yet). The available connectors will appear in a list beneath the selected node, as shown in Figure 2. Click in a box to select a connector, and it will be highlighted to indicate that it's selected. Then select the target node and choose '''Connect Node''' from the '''Node''' menu (or just type Ctrl-L). You will see a line with arrowheads pointing from the connector to its target node. Connectors from multiple nodes (one connector each) can be selected by using the Shift key. This can be useful if, for instance, you want to connect multiple zones to the same [[Fog Spaces | fog space]]. A connector can be broken by selecting it and choosing '''Unconnect Node''' from the '''Node''' menu (or typing Ctrl-U). <br clear=both> == See Also == * [http://c4engine.com/docs/WorldMgr/Connector.html <code>Connector</code>] class * [http://c4engine.com/docs/WorldMgr/Hub.html <code>Hub</code>] class [[Category:Editor]] b660096da4ee53fccc189530112fd9008e0ad658 Modifiers 0 422 425 2023-07-15T11:52:57Z Eric Lengyel 1 Created page with "__NOTOC__ A '''modifier''' is something that can be assigned to an instance node in order to change the appearance or properties of the world it references in some way. There are several modifiers built into the engine, and an application may define additional custom modifiers for its own use. Modifiers are assigned to an instance node in the [[World Editor]] under the '''Modifiers''' tab in the Node Info window. == Standard Modifiers == The following modifiers are bui..." wikitext text/x-wiki __NOTOC__ A '''modifier''' is something that can be assigned to an instance node in order to change the appearance or properties of the world it references in some way. There are several modifiers built into the engine, and an application may define additional custom modifiers for its own use. Modifiers are assigned to an instance node in the [[World Editor]] under the '''Modifiers''' tab in the Node Info window. == Standard Modifiers == The following modifiers are built into the core engine. {| {{Table}} {{Tablehead|Setting|Description}} |- {{Tablerow|'''Augment&nbsp;Instance'''|Loads another world alongside the instanced world. This can be useful for adding details to an object or adding physics to an object that is ordinarily immovable. The secondary world is instanced just like the originally instanced world, so data is shared among multiple instances of worlds loaded with this modifier. * The '''Instanced world name''' setting specifies the name of the world resource to be loaded.}} |- {{Tablerow|'''Wake&nbsp;Controller'''|Searches through all top-level nodes in the instanced world and wakes all controllers that are found.}} |- {{Tablerow|'''Sleep&nbsp;Controller'''|Searches through all top-level nodes in the instanced world and puts all controllers that are found to sleep.}} |- {{Tablerow|'''Connect&nbsp;Instance'''|Connects one of the outgoing connectors belonging to the instance node to a named node in the instanced world. * The '''Outgoing connector key''' setting specifies the connector attached to the instance node that will be connected to a node in the instanced world. * The '''Target node name''' setting specifies the name of the node inside the instanced world to which the connector will be connected.}} |- {{Tablerow|'''Move&nbsp;Connector&nbsp;Inside'''|Takes an incoming connector that is connected to the instance node from outside the instance and reconnects it to a named node inside the instanced world. * The '''Incoming connector key''' setting specifies the connector targeting the instance node that will be reconnected to a node inside the instanced world. * The '''Target node name''' setting specifies the name of the node inside the instanced world to which the connector will be connected.}} |- {{Tablerow|'''Move&nbsp;Connector&nbsp;Outside'''|Takes an incoming connector that is connected to the instance node from inside the instance and reconnects it to a node outside the instanced world. * The '''Incoming connector key''' setting specifies the connector targeting the instance node that will be reconnected to a node outside the instanced world. * The '''target connector key''' setting specifies the connector targeting a node outside the instanced world to which the connector will be connected.}} |- {{Tablerow|'''Enable&nbsp;Nodes'''|Enables a named node in the instanced world. * The '''Node type''' setting specifies the type of node inside the instanced world that will be enabled. If no name is specified then all nodes of this type are enabled. If the type is set to '''&lt;Any&gt;''', then any node with a matching name is enabled regardless of its type. * The '''Node name (blank for all)''' setting specifies the name of the node inside the instanced world that will be enabled. If no name is given, then all nodes matching the '''Node type''' setting are enabled.}} |- {{Tablerow|'''Disable&nbsp;Nodes'''|Disables a named node in the instanced world. * The '''Node type''' setting specifies the type of node inside the instanced world that will be disabled. If no name is specified then all nodes of this type are disabled. If the type is set to '''&lt;Any&gt;''', then any node with a matching name is disabled regardless of its type. * The '''Node name (blank for all)''' setting specifies the name of the node inside the instanced world that will be disabled. If no name is given, then all nodes matching the '''Node type''' setting are disabled.}} |- {{Tablerow|'''Delete&nbsp;Nodes'''|Deletes a named node in the instanced world. * The '''Node type''' setting specifies the type of node inside the instanced world that will be deleted. If no name is specified then all nodes of this type are deleted. If the type is set to '''&lt;Any&gt;''', then any node with a matching name is deleted regardless of its type. * The '''Node name (blank for all)''' setting specifies the name of the node inside the instanced world that will be deleted. If no name is given, then all nodes matching the '''Node type''' setting are deleted.}} |- {{Tablerow|'''Enable&nbsp;Interactivity'''|Enables interactivity for a named node in the instanced world. * The '''Node name (blank for all)''' setting specifies the name of the node inside the instanced world that will have interactivity enabled. The node must already have an interaction property assigned to it. If no name is given, then interactivity is enabled for all nodes in the instanced world that have interaction properties assigned to them.}} |- {{Tablerow|'''Disable&nbsp;Interactivity'''|Disables interactivity for a named node in the instanced world. * The '''Node name (blank for all)''' setting specifies the name of the node inside the instanced world that will have interactivity disabled. The node must already have an interaction property assigned to it. If no name is given, then interactivity is disabled for all nodes in the instanced world that have interaction properties assigned to them.}} |- {{Tablerow|'''Set&nbsp;Perspective&nbsp;Mask'''|Changes the perspective mask for nodes inside the instanced world having a specific type and/or name. * The '''Node type''' setting specifies the type of node inside the instanced world that will be modified. If no name is specified then all nodes of this type are modified. If the type is set to '''&lt;Any&gt;''', then any node with a matching name is modified regardless of its type. * The '''Node name (blank for all)''' setting specifies the name of the node inside the instanced world that will be modified. If no name is given, then all nodes matching the '''Node type''' setting are modified. * The check boxes under the '''Perspective Mask''' heading specify in what perspectives the modified nodes will be visible.}} |- {{Tablerow|'''Replace&nbsp;Material'''|Replaces the material for a named geometry node in the instanced world with the material assigned to the instance node itself. If no name is given, then the materials for all geometry nodes in the instanced world are replaced. * The '''Node name (blank for all)''' setting specifies the name of the node inside the instanced world that will have its material replaced.}} |- {{Tablerow|'''Remove&nbsp;Physics'''|Finds a top-level node having a [[Rigid Body Controller]] in the instanced world and removes the controller. This modifier also deletes any physics shapes and joints in the entire instanced world.}} |- {{Tablerow|'''Set&nbsp;Shape&nbsp;Substance'''|Sets the substance type for shape nodes inside the instanced world. * The '''Node name (blank for all)''' setting specifies the name of the node inside the instanced world that will be modified. If no name is given, then all shape nodes are modified. * The '''Shape substance''' setting specifies the substance type to assign to each shape node. Substance types are registered by the game module using the [http://c4engine.com/docs/GraphicsMgr/MaterialObject_RegisterSubstance.html <code>MaterialObject::RegisterSubstance</code> function].}} |} == See Also == * [http://c4engine.com/docs/WorldMgr/Modifier.html <code>Modifier</code> class] [[Category:Editor]] 30d364ee37f27205f2087b5a58ce2a42c7f5c2bb Material Editor 0 423 426 2023-07-15T11:54:24Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Materialeditor.png|right|frame|'''Figure 1.''' The Material Editor window.]] The '''Material Editor''' is a component of the [[World Editor]], and it is used to create materials by configuring a large set of specific attributes. Materials can also be created with the [[Shader Editor]], and this functionality is also accessed through the Material Editor. == Opening the Material Editor == The Material Editor is usually opened from inside the World Edit..." wikitext text/x-wiki __NOTOC__ [[File:Materialeditor.png|right|frame|'''Figure 1.''' The Material Editor window.]] The '''Material Editor''' is a component of the [[World Editor]], and it is used to create materials by configuring a large set of specific attributes. Materials can also be created with the [[Shader Editor]], and this functionality is also accessed through the Material Editor. == Opening the Material Editor == The Material Editor is usually opened from inside the [[World Editor]] by selecting '''Edit Material''' or '''New Material''' from the popup menu in the [[Material Page]]. (Double-clicking on an existing material is equivalent to selecting '''Edit Material'''.) The Material Editor can also be opened to create a new material resource or edit an existing material resource by selecting '''New Material''' or '''Open Material...''' from the [[C4 Menu]]. == See Also == * [[Material Page]] * [[Shader Editor]] * [[Texture Importer]] * [[Horizon Mapping]] [[Category:Shaders]] abcd672074d311136c74a88bb0dffbc720783d52 Shader Editor 0 424 427 2023-07-15T11:55:48Z Eric Lengyel 1 Created page with "__NOTOC__ There are two ways to create materials in the C4 Engine. The first method is to simply configure a set of predefined attributes in the [[Material Editor]]. This is the easiest and fastest way to create a new material, and most ordinary materials can be made using only those attributes. A more advanced method is to use the Shader Editor to define the exact calculations used by the engine to render a material. The Shader Editor provides you with the power to crea..." wikitext text/x-wiki __NOTOC__ There are two ways to create materials in the C4 Engine. The first method is to simply configure a set of predefined attributes in the [[Material Editor]]. This is the easiest and fastest way to create a new material, and most ordinary materials can be made using only those attributes. A more advanced method is to use the Shader Editor to define the exact calculations used by the engine to render a material. The Shader Editor provides you with the power to create a limitless variety of materials within the context of a graphical interface. == Opening the Shader Editor == [[File:Shadereditor.png|right|frame|'''Figure 1.''' The Shader Editor window.]] The image to the right shows the Shader Editor. The Shader Editor is opened from inside the [[Material Editor]] by choosing '''Edit Shader''' from the '''Material''' menu. If the selected material already had conventional attributes assigned to it through the settings in the Material Editor, then the Shader Editor will initially show a translation of those attributes into the shader graph. If the selected material was empty (because no settings had been specified for it yet), then the Shader Editor will initially show default graph with a minimal number of nodes. == Shader Graphs == A shader is represented in the Shader Editor by what is known as a ''data flow graph''. The nodes in this graph are called ''processes'', and the edges in this graph are called ''routes''. A shader is a special type of graph called a ''directed acyclic graph'', or ''DAG'', meaning that data flows in a specific direction from one process to another and there are no loops. Each box in the shader graph represents a single process. A process can be a simple mathematical operation, a constant input value such as a color, an interpolated value such as the direction to the light source, or a more complex operation defined by the engine such as a parallax offset calculation. A route is a directed edge shown as a curve with an arrowhead at one end, and it represents the flow of data from one process to another. Routes begin at one process and end at a ''port'' belonging to another process. Every process has between zero and four ports, and each can be occupied by only one incoming route at a time. Ports with a plain background are required, and ports with a striped background are optional. All required ports must have an incoming route attached to them in order for the shader to be valid. == Editing a Shader == The tabbed lists on the left side of the Shader Editor show the processes that are available for use in a shader. They are divided into four categories that are described in more detail below: Basic, Math, Complex, and Interpolants. A new process is added to a shader by selecting it in the list and then clicking in the viewport. The editor won't let you place two processes on top of each other, and the cursor will change to indicate where it's possible to place a new process. Routes are added to a shader by clicking inside the circle on the right side of a process and dragging into a port belonging to another process. This causes a new route to be created beginning at the process you clicked on and ending at the input port to which you dragged. If a port is already occupied by another route, then the existing route is deleted and replaced with the new route that you are creating. You cannot connect a route from one process to a port belonging to any other process preceding that process in the graph because it would create a cycle. The physical position of a process in the viewport is irrelevant. The data flow structure of a shader is determined entirely by the route connections. Processes may be placed in any convenient location. == Processes == A process takes between zero and four inputs and produces at most a single output. The output may be sent to any number of input ports for other processes. For many types of processes, the process box shown in the Shader Editor displays additional information. For example, the Texture Map process shows a small image of the texture map, and the Constant Vector process shows the four constant values that it outputs. Most mathematical operations display a mathematical expression showing exactly how their input values are used to calculate an output value. Double-clicking on a process, or selecting a process and typing Ctrl-I, opens the Process Info window for that process. In the Process Info window, every process has a comment field that let's you specify some text that is displayed at the bottom of the process box in the Shader Editor. Some processes also have extra settings that appear in the Process Info window. Each type of process available for use in a shader is described individually on the following pages (corresponding to the groups displayed in the Shader Editor): * [[Basic Shader Processes | List of basic processes]] * [[Mathematical Shader Processes | List of mathematical processes]] * [[Complex Shader Processes | List of complex processes]] * [[Interpolant Shader Processes | List of interpolant processes]] == Routes == The routes in a shader graph carry data from one process to another. Each route can carry between one and four floating-point values&mdash;the actual number is determined by the output size of the route's start process. A swizzle and negation may be applied to a route. These can be set by double-clicking on a route or by selecting a route and typing Ctrl-I. By default, the swizzle for a route is <code>xyzw</code>, meaning that there is no change to the order of the components. If any other swizzle is specified, or the values are negated, then that information is displayed in a small box at the center of the path representing the route. The swizzle may be specified using any letters from the sets <code>xyzw</code>, <code>rgba</code>, or <code>stpq</code>. Specifying only a single letter is shorthand for the same letter repeated four times. For example, the swizzle <code>z</code> is equivalent to the swizzle <code>zzzz</code>. If a route carries fewer than four components, then each component specified in its swizzle is clamped to the last available component. For example, if a route carries only three components, then any <code>w</code>, <code>a</code>, or <code>q</code> in the swizzle ultimately interpreted as the third component of the data carried by the route. The swizzle <code>wxyz</code> would really mean <code>zxyz</code>. This is particularly important in the case that two routes of different sizes are used as inputs to a binary operation. The operation is performed using the number of components for larger of the two routes, so the missing components of the smaller route are taken from the components specified by the clamped swizzle. == Shader Editor Tools == There are four tool buttons in the upper-left corner of the Shader Editor window, and they have the following uses. In addition to clicking on the tool button, each of these tools can also be selected by pressing the shortcut number key as shown in the table. (The shortcuts were chosen to be the same as the corresponding tools in the World Editor.) {| {{Table}} {{Tablehead3|Icon|Shortcut|Function}} |- {{Tablerow3|[[File:Tool_select.png]]|1|'''Select / Move'''. Selects a process or route in a shader. Clicking outside of a process and dragging will create a box that selects all of the processes inside it. Clicking inside a process and dragging moves all of the currently selected processes. (When processes are moved, they are automatically prevented from moving on top of other processes.)}} |- {{Tablerow3|[[File:Tool_scroll.png]]|6|'''Scroll'''. Scrolls the shader viewport. Holding the Alt key with any other tool temporarily selects the scroll tool.}} |- {{Tablerow3|[[File:Tool_zoom.png]]|7|'''Zoom'''. Changes the scale of the shader viewport. Using the mouse wheel with any other tool also zooms.}} |- {{Tablerow3|[[File:Tool_section.png]]||'''Draw Section'''. Draws a rectangular box with a title bar behind all processes in the graph. This can be used to visually organize groups of processes in a shader.}} |} == Output Processes == Each shader graph contains a set of ''output processes'' that represent the final values produced by the shader. These are colored green in the shader editor, they cannot be deleted, and they can have no output routes. The only output process that has a required input port is the '''Ambient Reflection Output''' process. All other output processes have only optional input ports and are ignored if they are not used. The individual output processes are described in the following table. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Ambient&nbsp;Reflection&nbsp;Output|Shader_ambientoutput.png|RGB color '''RGB''' (required), Normal '''N''' (optional)|None|This is the primary output process for the ambient shader. The color sent to this output process is combined with the ambient lighting environment to produce the final ambient light reflection for a material. The normal vector '''N''' is currently unused, but will be important in future ambient lighting models.}} |- {{Process|Light&nbsp;Reflection&nbsp;Output|Shader_lightingoutput.png|RGB color '''RGB''' (optional), Impostor depth '''Z''' (optional)|None|This is the primary output process for the light shader. The color sent to this output process is combined with the color from a light source to produce the final light reflection for a material. In an impostor shader, the alpha channel of the output of the Impostor Normal process should be sent to the '''Z''' input port to provide the impostor depth.}} |- {{Process|Alpha&nbsp;Output|Shader_alphaoutput.png|Scalar '''A''' (optional)|None|If a material is transparent, then the alpha value sent to this output process controls the transparency. This is currently useful only for objects rendered in the effect pass. If the Glow Output process is used, then the Alpha Output process is ignored.}} |- {{Process|Alpha&nbsp;Test&nbsp;Output|Shader_alphatestoutput.png|Scalar '''A''' (optional)|None|If a material uses the alpha test, then the value sent to this output process is the value that is tested. The material must have the alpha test flag set in the Material Manager for this output process to be used.}} |- {{Process|Emission&nbsp;Output|Shader_emissionoutput.png|RGB color '''RGB''' (optional)|None|The color sent to this output process is added to the final ambient color as an emission term.}} |- {{Process|Glow&nbsp;Output|Shader_glowoutput.png|Scalar '''A''' (optional)|None|If a material uses emission glow, then the value sent to this output process determines the glow intensity. The material must have the emission glow flag set in the Material Manager for this output process to be used. If the alpha test flag is set, then the Glow Output process is ignored.}} |- {{Process|Bloom&nbsp;Output|Shader_bloomoutput.png|Scalar '''A''' (optional)|None|If a material uses specular bloom, then the value sent to this output process determines the bloom intensity. The material must have the specular bloom flag set in the Material Manager for this output process to be used.}} |- {{Process|Reflection&nbsp;Buffer&nbsp;Output|Shader_reflectionoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the reflection buffer is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the reflection. Normal incidence reflectivity and bump offset scale can be configured in the settings for the process.}} |- {{Process|Refraction&nbsp;Buffer&nbsp;Output|Shader_refractionoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the refraction buffer is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the refraction. The bump offset scale can be configured in the settings for the process.}} |- {{Process|Environment&nbsp;Output|Shader_environmentoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process.}} |} == See Also == * [[Material Editor]] [[Category:Shaders]] c039c0fa85d644c84f01587a3d8ba56cff981140 Template:Process 10 425 428 2023-07-15T11:56:11Z Eric Lengyel 1 Created page with "| style="text-align: center; vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 24px 2px 6px;" | '''{{{1}}}''' [[File:{{{2}}}]] | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | '''Inputs:''' {{{3}}} '''Output:''' {{{4}}} {{{5}}}" wikitext text/x-wiki | style="text-align: center; vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 24px 2px 6px;" | '''{{{1}}}''' [[File:{{{2}}}]] | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | '''Inputs:''' {{{3}}} '''Output:''' {{{4}}} {{{5}}} ea27a10302250c08f3d048569534fa9f69cd5199 Category:Shaders 14 426 429 2023-07-15T11:56:32Z Eric Lengyel 1 Created blank page wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Basic Shader Processes 0 427 430 2023-07-15T11:57:27Z Eric Lengyel 1 Created page with "This is a list of the basic shader processes that are available in the [[Shader Editor]] under the Basic tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Constant Scalar|Shader_constantscalar.png|None|Scalar|Outputs a constant scalar value that is specified in the settings for the process. A ''parameter slot'' may be specified in the process settings. If the parameter slot is set to &ldquo;Constant&rdquo; (the default), then the output of this process c..." wikitext text/x-wiki This is a list of the basic shader processes that are available in the [[Shader Editor]] under the Basic tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Constant Scalar|Shader_constantscalar.png|None|Scalar|Outputs a constant scalar value that is specified in the settings for the process. A ''parameter slot'' may be specified in the process settings. If the parameter slot is set to &ldquo;Constant&rdquo; (the default), then the output of this process can never be changed while rendering. However, if one of the eight numbered parameter slots is selected, then it is possible to change the value output by this process without actually modifying the shader. For instance, the Set Shader Parameter script method can be used to change the output value of this process, effectively making it a variable parameter of the shader.}} |- {{Process|Constant Vector|Shader_constantvector.png|None|4D vector|Outputs a constant vector value that is specified in the settings for the process. See the note about parameter slots under the Constant Scalar process.}} |- {{Process|Constant Color|Shader_constantcolor.png|None|RGBA color|Outputs a constant color value that is specified in the settings for the process. See the note about parameter slots under the Constant Scalar process.}} |- {{Process|Shader Time|Shader_time.png|None|Scalar|Outputs a scalar value in the range [0,1) representing the current shader time. The shader time runs from 0 to 1 over a period of 120 seconds and then repeats by wrapping back to 0.}} |- {{Process|Fragment Depth|Shader_fragmentdepth.png|None|Scalar|Outputs a scalar value equal to the depth of the fragment in camera space.}} |- {{Process|Primitive Facing|Shader_primitivefacing.png|None|Scalar|Outputs a scalar value that is +1.0 for front-facing primitives and &minus;1.0 for back-facing primitives.}} |- {{Process|Merge 2D|Shader_merge2d.png|Scalar '''x''' (required), Scalar '''y''' (required)|2D vector|Combines the two scalar inputs '''x''' and '''y''' into a single 2D vector output.}} |- {{Process|Merge 3D|Shader_merge3d.png|Scalar '''x''' (required), Scalar '''y''' (required), Scalar '''z''' (required)|3D vector|Combines the three scalar inputs '''x''', '''y''', and '''z''' into a single 3D vector output.}} |- {{Process|Merge 4D|Shader_merge4d.png|Scalar '''x''' (required), Scalar '''y''' (required), Scalar '''z''' (required), Scalar '''w''' (required)|4D vector|Combines the four scalar inputs '''x''', '''y''', '''z''', and '''w''' into a single 4D vector output.}} |- {{Process|Texture Map|Shader_texturemap.png|2D or 3D vector '''TEXC''' (required)|RGBA color|Samples a texture map using the input texture coordinates '''TEXC'''. The texture map is specified in the settings for the process. The size of the input '''TEXC''' is determined by the type of the texture map. The input is a 2D vector for 2D and Rect textures, and the size is a 3D vector for 3D, Cube, and Array 2D textures. Note that this process should not be used for normal maps. Use the Normal Map process instead.}} |- {{Process|Normal Map|Shader_normalmap.png|2D vector '''TEXC''' (required)|3D vector|Samples a normal map using the input texture coordinates '''TEXC'''. The normal map is specified in the settings for the process.}} |- {{Process|Paint Texture|Shader_painttexture.png|2D vector '''TEXC''' (required)|RGBA color|Samples a paint space texture map using the input texture coordinates '''TEXC'''. The texture map is determined by what paint space is associated with the geometry being rendered. The input vector is normally the output of the Paint Texcoord [[Interpolant Shader Processes|interpolant process]].}} |- {{Process|Terrain Texture|Shader_terraintexture.png|None|RGBA color|Samples a terrain texture palette. The texture map is specified in the settings for the process. Note that this process should not be used for terrain normal maps. Use the Terrain Normal process instead.}} |- {{Process|Terrain Normal 1, 2, 3|Shader_terrainnormal1.png|None|3D vector|Samples a terrain normal palette. The normal map is specified in the settings for the process. If one of these three processes exists, then all three should exist and should use the same normal map. Their outputs should be sent to a Terrain Diffuse Reflection and/or Terrain Specular Reflection process.}} |- {{Process|Impostor Texture|Shader_impostortexture.png|None|RGBA color|Samples an impostor texture map. The texture map is specified in the settings for the process. Note that this process should not be used for impostor normal maps. Use the Impostor Normal process instead.}} |- {{Process|Impostor Normal|Shader_impostornormal.png|None|3D vector|Samples an impostor normal map. The normal map is specified in the settings for the process.}} |} == See Also == * [[Shader Editor]] * [[Mathematical Shader Processes]] * [[Complex Shader Processes]] * [[Interpolant Shader Processes]] [[Category:Shaders]] 0f455fcdfc20835c21956e8b14fc5d858eeb5e63 Mathematical Shader Processes 0 428 431 2023-07-15T11:58:30Z Eric Lengyel 1 Created page with "This is a list of the mathematical shader processes that are available in the [[Shader Editor]] under the Math tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Absolute Value|Shader_abs.png|Value '''A'''|Value of size matching '''A'''|Calculates the absolute value of each component of the input '''A'''.}} |- {{Process|Add|Shader_add.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise sum of the..." wikitext text/x-wiki This is a list of the mathematical shader processes that are available in the [[Shader Editor]] under the Math tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Absolute Value|Shader_abs.png|Value '''A'''|Value of size matching '''A'''|Calculates the absolute value of each component of the input '''A'''.}} |- {{Process|Add|Shader_add.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise sum of the inputs '''A''' and '''B'''.}} |- {{Process|Average|Shader_avg.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise average of the inputs '''A''' and '''B'''.}} |- {{Process|Cosine|Shader_cos.png|Scalar '''A'''|Scalar|Calculates the cosine of the input '''A''', where the input is measured in radians.}} |- {{Process|Cross Product|Shader_xpd.png|3D vectors '''A''' and '''B'''|3D vector|Calculates the cross product of the inputs '''A''' and '''B'''.}} |- {{Process|Divide|Shader_div.png|Value '''A''', Scalar '''B'''|Value of size matching '''A'''|Calculates the quotient of each component of the input '''A''' and the scalar input '''B'''. ''Tip:'' If you're dividing by a constant value, then it would be more efficient to multiply by the reciprocal of the constant. For example, you should multiply by 0.5 instead of dividing by 2.0.}} |- {{Process|Dot Product 3D|Shader_dp3.png|3D vectors '''A''' and '''B'''|Scalar|Calculates the dot product of the inputs '''A''' and '''B'''.}} |- {{Process|Dot Product 4D|Shader_dp4.png|4D vectors '''A''' and '''B'''|Scalar|Calculates the dot product of the inputs '''A''' and '''B'''.}} |- {{Process|Exp Base 2|Shader_ex2.png|Scalar '''A'''|Scalar|Calculates 2 raised to the power given by the input '''A'''.}} |- {{Process|Expand|Shader_expand.png|Value '''A'''|Value of size matching '''A'''|Multiplies each component of the input '''A''' by 2.0 and then subtracts 1.0.}} |- {{Process|Floor|Shader_flr.png|Value '''A'''|Value of size matching '''A'''|Calculates the floor of each component of the input '''A'''. To calculate a ceiling, negate the input and output of the Floor process.}} |- {{Process|Fraction|Shader_frc.png|Value '''A'''|Value of size matching '''A'''|Calculates the fraction of each component of the input '''A'''. The fraction of a number is the difference between that number and its floor.}} |- {{Process|Invert|Shader_invert.png|Value '''A'''|Value of size matching '''A'''|Subtracts each component of the input '''A''' from 1.0.}} |- {{Process|Linear Interpolate|Shader_lrp.png|Values '''A''', '''B''', and '''t'''|Value of size matching largest of '''A''', '''B''', and '''t'''|Calculates the linear interpolation between the components of '''A''' and '''B''' using the components of the input '''t''' as the interpolation parameter.}} |- {{Process|Log Base 2|Shader_lg2.png|Scalar '''A'''|Scalar|Calculates the logarithm base 2 of the input '''A'''. If the input is not positive, then the result is undefined.}} |- {{Process|Magnitude 3D|Shader_magnitude3d.png|3D vector '''A'''|Scalar|Calculates the magnitude of the input '''A'''.}} |- {{Process|Maximum|Shader_max.png|Values '''A''' and '''B''' (required), value '''C''' (optional)|Value of size matching larger of '''A''', '''B''', and '''C'''|Calculates the componentwise maximum of the inputs '''A''', '''B''', and '''C'''. If input '''C''' is omitted, then the maximum of only '''A''' and '''B''' is calculated.}} |- {{Process|Minimum|Shader_min.png|Values '''A''' and '''B''' (required), value '''C''' (optional)|Value of size matching larger of '''A''', '''B''', and '''C'''|Calculates the componentwise minimum of the inputs '''A''', '''B''', and '''C'''. If input '''C''' is omitted, then the minimum of only '''A''' and '''B''' is calculated.}} |- {{Process|Multiply|Shader_mul.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise product of the inputs '''A''' and '''B'''.}} |- {{Process|Multiply Add|Shader_mad.png|Values '''A''', '''B''', and '''C'''|Value of size matching largest of '''A''', '''B''', and '''C'''|Calculates the componentwise product of the inputs '''A''' and '''B''' and then adds the components of the input '''C'''.}} |- {{Process|Normalize 3D|Shader_normalize3d.png|3D vector '''A'''|3D vector|Normalizes the input '''A'''. If the input is the zero vector, then the result is undefined.}} |- {{Process|Power|Shader_pow.png|Scalars '''A''' and '''B'''|Scalar|Calculates the input '''A''' raised to the power of the input '''B'''. If the input '''A''' is negative, then the result is undefined. If the input '''A''' is zero and the input '''B''' is not positive, then the result is undefined. ''Tip:'' If you're just squaring a value, then it would be more efficient to multiply the value by itself. That is, you should calculate '''A'''&nbsp;&times;&nbsp;'''A''' using the '''Multiply''' process instead of raising '''A''' to the power of 2.}} |- {{Process|Reciprocal|Shader_rcp.png|Scalar '''A'''|Scalar|Calculates the reciprocal of the input '''A'''. If the input is zero, then the result is undefined.}} |- {{Process|Reciprocal Square Root|Shader_rsq.png|Scalar '''A'''|Scalar|Calculates the reciprocal square root of the input '''A'''. If the input is not positive, then the result is undefined.}} |- {{Process|Round|Shader_round.png|Value '''A'''|Value of size matching '''A'''|Rounds each component of the input '''A''' to the nearest integer.}} |- {{Process|Saturate|Shader_sat.png|Value '''A'''|Value of size matching '''A'''|Clamps each component of the input '''A''' to the range [0,1].}} |- {{Process|Set if Equal|Shader_seq.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set if Greater Equal|Shader_sge.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is greater than or equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set if Greater Than|Shader_sgt.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is greater than the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set if Less Equal|Shader_sle.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is less than or equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set of Less Than|Shader_slt.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is less than the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set if Not Equal|Shader_sne.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is not equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Sine|Shader_sin.png|Scalar '''A'''|Scalar|Calculates the sine of the input '''A''', where the input is measured in radians.}} |- {{Process|Square Root|Shader_sqrt.png|Scalar '''A'''|Scalar|Calculates the square root of the input '''A'''. If the input is negative, then the result is undefined.}} |- {{Process|Subtract|Shader_sub.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise difference of the inputs '''A''' and '''B'''.}} |} == See Also == * [[Shader Editor]] * [[Basic Shader Processes]] * [[Complex Shader Processes]] * [[Interpolant Shader Processes]] [[Category:Shaders]] 94cce0c2bb9d505e067c0b473b8e1723bdbd8338 Complex Shader Processes 0 429 432 2023-07-15T11:59:05Z Eric Lengyel 1 Created page with "This is a list of the complex shader processes that are available in the [[Shader Editor]] under the Complex tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Diffuse Reflection|Shader_diffuse.png|Tangent-space normal '''N''' (optional)|Scalar|Calculates the Lambertian diffuse reflection factor '''N'''&nbsp;&middot;&nbsp;'''L''', where '''L''' is the tangent-space direction to light. The result is saturated to the range [0,1]. If '''N''' is omitted, then..." wikitext text/x-wiki This is a list of the complex shader processes that are available in the [[Shader Editor]] under the Complex tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Diffuse Reflection|Shader_diffuse.png|Tangent-space normal '''N''' (optional)|Scalar|Calculates the Lambertian diffuse reflection factor '''N'''&nbsp;&middot;&nbsp;'''L''', where '''L''' is the tangent-space direction to light. The result is saturated to the range [0,1]. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Specular Reflection|Shader_specular.png|Tangent-space normal '''N''' (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor ('''N'''&nbsp;&middot;&nbsp;'''H''')<sup>''p''</sup>, where '''H''' is the tangent-space direction halfway between the direction to light and direction to viewer. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). The specular power ''p'' controls the sharpness of the specularity. This process implicitly uses the tangent halfway direction interpolant, which in turn uses the tangent light direction and tangent view direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Microfacet Reflection|Shader_microfacet.png|Tangent-space normal '''N''' (optional)|RGB color|Calculates the Cook-Torrance microfacet reflection color. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). This process implicitly uses the tangent light direction, tangent view direction, and tangent halfway direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Terrain Diffuse Reflection|Shader_terraindiffuse.png|Terrain normal '''N'''<sub>1</sub> (optional), Terrain normal '''N'''<sub>2</sub> (optional), Terrain normal '''N'''<sub>3</sub> (optional)|Scalar|Calculates the Lambertian diffuse reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Terrain Specular Reflection|Shader_terrainspecular.png|Terrain normal '''N'''<sub>1</sub> (optional), Terrain normal '''N'''<sub>2</sub> (optional), Terrain normal '''N'''<sub>3</sub> (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. The specular power ''p'' controls the sharpness of the specularity. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Combine Normals|Shader_combinenormals.png|Normal vector '''N'''<sub>1</sub> (required), Normal vector '''N'''<sub>2</sub> (required), Scalar ''t'' (optional)|3D vector|If ''t'' is omitted, calculates a new normal vector corresponding to the normal that would be produced if the two height maps producing the input normals were added together. If ''t'' is not omitted, then it determines how the heights are weighted, with the height corresponding to '''N'''<sub>1</sub> being weighted most when ''t'' is zero and the height corresponding to '''N'''<sub>2</sub> being weighted most when ''t'' is one. A value for ''t'' of 0.5 does produces an average height, which is not the same as the sum produces when ''t'' is omitted.}} |- {{Process|Front Normal|Shader_frontnormal.png|Normal vector '''N''' (required)|3D vector|Calculates a new normal vector by negating the ''z'' component of the input vector if the ''z'' component of the tangent-space light direction is negative. Otherwise, the input vector is passed through unchanged. This is useful when rendering two-sided triangles with a normal map because it has the effect of always facing the normal vector to the front with respect to the light direction. This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined. ''Tip:'' This process should not be used in impostor shaders.}} |- {{Process|Reflect Vector|Shader_reflectvector.png|3D vector '''V''' (required), 3D vector '''N''' (optional)|3D vector|Calculates the reflection of the vector '''V''' across the vector '''N'''. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).}} |- {{Process|Smooth Parameter|Shader_smooth.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 3''t''<sup>2</sup>&nbsp;&minus;&nbsp;2''t''<sup>3</sup> componentwise. This has the effect of smoothing an interpolation parameter within the range [0,1] since the derivative at both endpoints is zero.}} |- {{Process|Steep Parameter|Shader_steep.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 2''t''&nbsp;&minus;&nbsp;''t''<sup>2</sup> componentwise. This has the effect of making an interpolation start quickly at a steep slope and finish smoothly.}} |- {{Process|Linear Ramp|Shader_linearramp.png|Value '''A''' (required)|Value of size matching '''A'''|Remaps the range [''c''&nbsp;&minus;&nbsp;&frac12;''w'',&nbsp;''c''&nbsp;+&nbsp;&frac12;''w''] to the range [0,1] componentwise, where ''c'' is a center value and ''w'' is the width of the input range. The values of ''c'' and ''w'' are specified in the settings for the process.}} |- {{Process|Delta Depth|Shader_deltadepth.png|None|Scalar|Outputs the difference between the depth of the geometry in the structure buffer and the depth of the fragment being shaded, scaled by a factor ''s'' and clamped to the range [0,1]. The scale factor ''s'' is specified in the settings for the process. If rendering to the structure buffer is disabled, then the output value is always 1.0.}} |- {{Process|Tangent to World Transform|Shader_tangenttoworld.png|3D vector '''V''' (required)|3D vector|Transforms the vector '''V''' from tangent space coordinates into world space coordinates. This process implicitly uses three 3D vector interpolants containing the matrix that transforms from tangent space to world space.}} |- {{Process|Parallax Offset|Shader_parallax.png|2D vector '''TEXC''' (required)|2D vector|Perturbs the input texture coordinates using the parallax information in the normal map and outputs the result. The normal map is specified in the settings for the process. If parallax mapping is disabled, then the input texture coordinates '''TEXC''' are simply passed through to the output. This process implicitly uses the tangent view direction interpolant.}} |- {{Process|Horizon Shadow|Shader_horizon.png|2D vector '''TEXC''' (required), RGB color '''RGB''' (required)|RGB color|Calculates the horizon map shadowing based on the two input horizon map sampled at the texture coordinates '''TEXC''' and multiplies the input color '''RGB''' by the amount of light reaching the surface. The horizon map is specified in the settings for the process. Flags for excluding horizon mapping for infinite or points lights can also be set. If horizon mapping is disabled or the shader is used in conjunction with a light type that has been excluded, then the input color '''RGB''' is simply passed through to the output. This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Kill Fragment|Shader_kill.png|Scalar '''A''' (required), Scalar '''B''' (optional)|None|Kills the current fragment if '''A''' &lt; '''B'''. If '''B''' is omitted, then the fragment is killed if '''A''' &lt; 0.}} |} == See Also == * [[Shader Editor]] * [[Basic Shader Processes]] * [[Mathematical Shader Processes]] * [[Interpolant Shader Processes]] [[Category:Shaders]] 68e606bcbac85f70c931337885a278a5f354e1fd Interpolant Shader Processes 0 430 433 2023-07-15T11:59:47Z Eric Lengyel 1 Created page with "__NOTOC__ When the graphics hardware renders a triangle, some values are calculated at each pixel and other values are calculated only at the vertices. The values calculated at the vertices are smoothly varied across the interior of a triangle through a process called perspective-correct interpolation. Hence, these values are called ''interpolants''. The list below describes each of the interpolants available for use in the [[Shader Editor]] under the Interpolants tab...." wikitext text/x-wiki __NOTOC__ When the graphics hardware renders a triangle, some values are calculated at each pixel and other values are calculated only at the vertices. The values calculated at the vertices are smoothly varied across the interior of a triangle through a process called perspective-correct interpolation. Hence, these values are called ''interpolants''. The list below describes each of the interpolants available for use in the [[Shader Editor]] under the Interpolants tab. == Interpolant Allocation == The graphics hardware can only handle so many interpolants, so there is a limit to how many can be used in a single shader. (The ambient and light graphs shown in the editor represent distinct shaders, so any interpolants used in one do not count against the other.) The limit is based on the availability of eight 4D vectors that the hardware provides for texture coordinates, or ''texcoords''. We call these the eight texcoord slots. Among these slots, there are a total of exactly 32 scalar values that can be calculated at each vertex and interpolated across a triangle. However, interpolants that need 2, 3, or 4 values cannot be split up, so it may not be possible to pack all of the interpolants into the texcoord slots even though there is enough room for each of the component values. Furthermore, lighting and fog calculations that are not explicitly displayed in the shader graph need some of their own interpolants, so the number of usable texcoord slots is somewhat less than the full eight that exist in the hardware. The shader compiler allocates interpolants to texcoord slots as follows: * For any four-component interpolant, one entire texcoord slot is consumed. * For any three-component interpolant, the first three components of a single texcoord slot are consumed. The fourth component can be used by a different one-component interpolant. * For any two-component interpolant, either the first two or last two components of a single texcoord slot are consumed. If the first half of a texcoord slot is allocated, then the second half can be used by another two-component interpolant, or it can be used by two one-component interpolants. * For any one-component interpolant, the first available unused component of any texcoord slot is consumed. Interpolants are allocated in order of size from largest to smallest so that a bunch of small interpolants can't prevent a large interpolant from being allocated when there should be room. Unless otherwise noted below, each interpolant provided in the Shader Editor requires the number of components in its output value. == Coordinate Spaces == There are three different coordinate systems that can be used in shaders: tangent-space coordinates, object-space coordinates, and world-space coordinates. ''Tangent space'' is a special coordinate system that is required for normal mapping. In tangent space, the ''z'' axis is always aligned with the vertex normal, and the ''x'' axis is always aligned with the vertex tangent (which is aligned with the ''s'' direction of the texture coordinates). In the interior of a triangle, the tangent space is a blend of the tangent spaces at each of the three vertices. By definition, the normal vector in tangent space is always (0,0,1). Similarly, the tangent direction is always (1,0,0), and the bitangent direction is always (0,1,0). ''Object space'' is the local coordinate space for an individual object. In object space, the normals and tangents are exactly those that are stored in the vertex arrays for an object. It is unusual for object-space coordinates to be used in a shader. The use of tangent-space coordinates is preferred because it is more efficient. ''World space'' is the global coordinate system. The use of world-space coordinates is normally only needed when sampling cube texture maps. == Interpolants == {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Texcoord 1|Shader_texcoord1.png|None|2D vector|The primary texture coordinates.}} |- {{Process|Texcoord 2|Shader_texcoord2.png|None|2D vector|The secondary texture coordinates.}} |- {{Process|Paint Texcoord|Shader_painttexcoord.png|None|2D vector|The paint space texture coordinates. These are determined by the paint space associated with the geometry being rendered. The output of this process is normally fed into a Paint Texture [[Basic Shader Processes|basic process]].}} |- {{Process|Vertex Color|Shader_vertexcolor.png|None|RGBA color|The vertex color. The vertex color does not occupy any texcoord slots.}} |- {{Process|Vertex Geometry|Shader_vertexgeometry.png|None|3D vector|This interpolant can be used with water shaders when land elevation data has been generated for water geometries. The ''z'' component contains the difference in height between the water surface and the land beneath it, and the ''x'' and ''y'' components contain the gradient of the land elevation.}} |- {{Process|Tangent-Space Light Direction|Shader_tangentlight.png|None|3D vector|The unit-length tangent-space direction to light '''L'''. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Tangent-Space View Direction|Shader_tangentview.png|None|3D vector|The unit-length tangent-space direction to viewer '''V'''.}} |- {{Process|Tangent-Space Halfway Direction|Shader_tangenthalfway.png|None|3D vector|The unit-length tangent-space direction vector '''H'''. The halfway direction does not occupy any texcoord slots by itself, but it implicitly requires the light direction and view direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Object-Space Light Direction|Shader_objectlight.png|None|3D vector|The unit-length object-space direction to light '''L'''. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Object-Space View Direction|Shader_objectview.png|None|3D vector|The unit-length object-space direction to viewer '''V'''.}} |- {{Process|Object-Space Halfway Direction|Shader_objecthalfway.png|None|3D vector|The unit-length object-space halfway direction '''H'''. The halfway direction does not occupy any texcoord slots by itself, but it implicitly requires the light direction and view direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Object-Space Vertex Position|Shader_objectposition.png|None|3D vector|The object-space vertex position '''P'''.}} |- {{Process|Object-Space Normal|Shader_objectnormal.png|None|3D vector|The object-space vertex normal '''N'''.}} |- {{Process|Object-Space Tangent|Shader_objecttangent.png|None|3D vector|The object-space vertex tangent '''T'''.}} |- {{Process|Object-Space Bitangent|Shader_objectbitangent.png|None|3D vector|The object-space vertex bitangent '''B'''.}} |- {{Process|World-Space Vertex Position|Shader_worldposition.png|None|3D vector|The world-space vertex position '''P'''.}} |- {{Process|World-Space Normal|Shader_worldnormal.png|None|3D vector|The world-space vertex normal '''N'''.}} |- {{Process|World-Space Tangent|Shader_worldtangent.png|None|3D vector|The world-space vertex tangent '''T'''.}} |- {{Process|World-Space Bitangent|Shader_worldbitangent.png|None|3D vector|The world-space vertex bitangent '''B'''.}} |- {{Process|Full Tangent-Space Light Vector|Shader_fulltangentlight.png|None|3D vector|The full-length tangent-space direction to light '''L'''. This is the difference between the light position and vertex position in tangent space.}} |- {{Process|Full Tangent-Space View Vector|Shader_fulltangentview.png|None|3D vector|The full-length tangent-space direction to viewer '''V'''. This is the difference between the camera position and vertex position in object space.}} |- {{Process|Full Object-Space Light Vector|Shader_fullobjectlight.png|None|3D vector|The full-length object-space direction to light '''L'''. This is the difference between the light position and vertex position in object space.}} |- {{Process|Full Object-Space View Vector|Shader_fullobjectview.png|None|3D vector|The full-length object-space direction to viewer '''V'''. This is the difference between the camera position and vertex position in object space.}} |} == See Also == * [[Shader Editor]] * [[Basic Shader Processes]] * [[Mathematical Shader Processes]] * [[Complex Shader Processes]] [[Category:Shaders]] 972b17a0b8df1de5f80f53c9dceeaf656988693f Script Editor 0 431 434 2023-07-15T12:01:02Z Eric Lengyel 1 Created page with "__NOTOC__ The C4 Engine contains a powerful scripting language that can be used to implement event sequences taking place in response to some kind of trigger in a world. A script does not require the use of any textual programming language. Instead, a script is shown as a graphical representation of the actions to be performed and their interdependencies. Scripts support local and global variables, conditional execution, loops, and expression evaluation. For information..." wikitext text/x-wiki __NOTOC__ The C4 Engine contains a powerful scripting language that can be used to implement event sequences taking place in response to some kind of trigger in a world. A script does not require the use of any textual programming language. Instead, a script is shown as a graphical representation of the actions to be performed and their interdependencies. Scripts support local and global variables, conditional execution, loops, and expression evaluation. For information about creating custom script methods, see [[Defining a Custom Method]]. For information about the use of expressions in scripts, see [[Expression Evaluation in Scripts]]. == Adding a Script to the World == [[File:Scripteditor.png|right|frame|'''Figure 1.''' The Script Editor window.]] The image to the right shows the Script Editor. A script can be assigned to any node in a world and edited by attaching the script controller to it as follows. # In the World Editor, select the node to which you would like to assign a script. # Choose '''Node Info''' from the '''Node''' menu or just press Ctrl-I. # Click on the Controller tab in the Node Info dialog. # Select the Script controller from the list of available controllers. # Click on the Edit Script button that appears to open the Script Editor. A script can also be assigned to any item inside a panel effect. For more information, see [[Panel Editor]]. An existing script can be edited by selecting a node and choosing '''Edit Script or Panel''' from the '''Node''' menu, or by just pressing Ctrl-E. You can also access the script by following the same steps above, except that the script controller will already be selected in the Node Info window. == Script Events == A script controller can contain multiple scripts, and these are displayed in a list in the upper-left corner of the Script Editor. Each script can be configured to handle one or more different ''events'' that cause the script to be executed. When a specific event is send to a script controller, ''all'' of the scripts that can handle that event are executed. Double-clicking on a script name opens the Script Info window, which displays the following settings. {| {{Table}} {{Tablehead|Setting|Description}} |- {{Tablerow|'''Script&nbsp;name'''|The name of the script. This is used only to identify the script in the Script Editor.}} |- {{Tablerow|'''Handles&nbsp;controller&nbsp;activate&nbsp;event'''|If checked, then the script is executed in response to an activate event being sent to the script controller. This is available only for scripts attached to nodes.}} |- {{Tablerow|'''Handles&nbsp;controller&nbsp;deactivate&nbsp;event'''|If checked, then the script is executed in response to a deactivate event being sent to the script controller. This is available only for scripts attached to nodes.}} |- {{Tablerow|'''Handles&nbsp;widget&nbsp;activate&nbsp;event'''|If checked, then the script is executed in response to an activate event being sent to the widget, which happens when the user clicks a button or activates a widget in some way that causes an action to take place. This is available only for scripts attached to widgets.}} |- {{Tablerow|'''Handles&nbsp;widget&nbsp;change&nbsp;event'''|If checked, then the script is executed in response to a change event being sent to the widget, which happens when the user modifies the value of a widget. This is available only for scripts attached to widgets.}} |- {{Tablerow|'''Handles&nbsp;widget&nbsp;begin&nbsp;hover&nbsp;event'''|If checked, then the script is executed in response to a begin hover event being sent to the widget, which happens when the cursor enters the widget. This is available only for scripts attached to widgets.}} |- {{Tablerow|'''Handles&nbsp;widget&nbsp;end&nbsp;hover&nbsp;event'''|If checked, then the script is executed in response to an end hover event being sent to the widget, which happens when the cursor exits the widget. This is available only for scripts attached to widgets.}} |} A single script may perform different actions in response to different events by using the [[Methods#Event Methods|event methods]] available in the Script Editor. == Script Execution == The graphical representation shown in the Script Editor is known as a ''control flow graph''. The nodes in this graph are called ''methods'', and the edges in this graph are called ''fibers''. A method is shown as a box in the Script Editor, and it represents a single action in the script. What a particular method actually does is determined by the C++ code that defines that method. The C++ code for many methods is built into the core engine, and the game code can implement new C++ code for any number of custom methods. A method can produce both a boolean result and a separate output value that can be stored in a script variable. The boolean result is used for conditional execution, and the output value may be used as an input for another method. A fiber is a directed edge shown as a curve with an arrowhead at one end, and it represents the flow of execution from one method to another. The method from which the fiber starts is called the start method for the fiber, and the method to which the fiber points is called the finish method for the fiber. Each fiber possesses an execution mode that is one of the following values, and this mode controls conditional execution. * Execute always. The fiber is followed regardless of the boolean result produced by its start method. These fibers are colored black. * Execute on condition true. The fiber is followed only if the boolean result produced by its start method was true. These fibers are colored green and display a box containing the letter T. * Execute on condition false. The fiber is followed only if the boolean result produced by its start method was false. These fibers are colored red and display a box containing the letter F. A fiber that represents a loop in the script is shown as a dashed curve. Looping fibers (also known as back edges) are detected automatically by the Script Editor and cannot be specified as looping or not looping by the user. When a script begins execution, the methods having no incoming fibers are visited first and executed. These methods are automatically colored green in the Script Editor. When a method finishes executing, each of its outgoing fibers is signaled as either live or dead depending on the boolean result of the method and the execution mode of the fiber. Any fibers that are not dead looping fibers are signaled as ready. A subsequent method is executed whenever (a) ''all'' of its incoming non-looping fibers are ready or (b) ''any'' of its looping incoming fibers are ready. If any of the fibers are live, then the next method is executed normally. If all of the fibers are dead, then the next method is skipped, but its non-looping outgoing fibers are still signaled as in the ready and dead state. This model allows execution to continue past points where different conditionally executed paths join back together. Multiple fibers leaving a particular method can be thought of as executing in parallel from a high-level perspective. Since they are actually executed serially at the low level in a cooperatively scheduled fashion, the edges representing control flow in a script are reminiscent of operating system fibers, and that is where they get their name. The order in which methods immediately succeeding a completed method are executed is unspecified, except for the restriction that all incoming non-looping fibers must be ready. Methods are colored red in the case that the user creates a closed loop having no incoming fibers from methods not belonging to a cycle in the graph. Methods in such a loop can never be executed, so the red color provides an indication of dead code. This situation can be corrected by adding a null method to the graph and drawing a fiber between it and the first method that should execute in the loop. == Editing a Script == The tabbed lists on the left side of the Script Editor show the [[Methods | methods]] that are available for use in a script. The Basic and Standard tabs contain methods that are implemented by the core engine, and the Custom tab contains methods that are implemented by the game code. When the Script Editor is opened for the first time for a particular node in a world or widget in a panel, the script viewport is blank. New methods can be added to the script by selecting them from the lists and clicking in the viewport. The editor won't let you place two methods on top of each other, and the cursor will change to indicate where it's possible to place a new method. Fibers are added to a script by clicking inside the circle at the bottom of any method and dragging into another method. This causes a new fiber to be created beginning at the method you clicked on and ending at the method inside which the mouse was released. You cannot create multiple fibers between the same two methods. The execution mode of a fiber can be changed by selecting the '''Cycle Fiber Condition''' command from the '''Script''' menu or using the shortcut Ctrl-F. The physical position of a method in the viewport is irrelevant. The execution flow structure of a script is determined entirely by the fiber connections. Methods may be placed in any convenient location. == Script Editor Tools == There are four tool buttons in the upper-left corner of the Script Editor window, and they have the following uses. In addition to clicking on the tool button, each of these tools can also be selected by pressing the shortcut number key as shown in the table. (The shortcuts were chosen to be the same as the corresponding tools in the World Editor.) {| {{Table}} {{Tablehead3|Icon|Shortcut|Function}} |- {{Tablerow3|[[File:Tool_select.png]]|1|'''Select / Move.''' Selects a method or fiber in a script. Clicking outside of a method and dragging will create a box that selects all of the methods inside it. Clicking inside a method and dragging moves all of the currently selected methods. (When methods are moved, they are automatically prevented from moving on top of other methods.)}} |- {{Tablerow3|[[File:Tool_scroll.png]]|6|'''Scroll.''' Scrolls the script viewport. Holding the Alt key with any other tool temporarily selects the scroll tool.}} |- {{Tablerow3|[[File:Tool_zoom.png]]|7|'''Zoom.''' Changes the scale of the script viewport. Using the mouse wheel with any other tool also zooms.}} |- {{Tablerow3|[[File:Tool_section.png]]||'''Draw Section.''' Draws a rectangular box with a title bar behind all methods in the graph. This can be used to visually organize groups of methods in a script. Sections have no effect on script functionality.}} |} == Method Settings == Each method may expose a group of configurable settings that can be accessed in a Method Info window. To edit them, select a single method and select Get Info from the Script menu or use the shortcut Ctrl-I. Double-clicking on a method will also open its Method Info window. The layout of the Method Info window depends on the type of the selected method. In all cases, the configurable settings for the method are displayed on the right side of the Method Info window. A column entitled "Input Variables" is also shown that let's you specify that a variable should be used as the input for a setting instead of any constant value entered in the window. (See below for more information about variables in scripts.) Most methods operate on some node in the scene, called the ''target'' of the method. The target node may be chosen from the list in the upper-left corner of the Method Info window. The target node may be any of the following nodes. * The target node of the script controller itself. This is called &lt;Script Node&gt; in the Script Editor, it's the same node that the script is attached to. * The node that ultimately initiated the script by activating the trigger node. This is called &lt;Initiator Node&gt; in the Script Editor. * The trigger node that was activated and caused the script to execute, if any. This is called &lt;Trigger Node&gt; in the Script Editor. * Any node that is connected to the target node of the controller. (See [[Connectors]] for information about making connections between nodes.) Once a target node has been selected for a method, it is displayed in parentheses under the method's name in the script viewport. === Call Controller Function Method === If a method is of type "Call Controller Function", then a list of available controller functions for the selected target node is displayed on the left side of the Method Info window. Once a function is selected, its configurable settings are displayed in the list on the right side of the window. If a function outputs a value, then a field for designating an output variable also appears in the lower-left corner of the window. For a description of the functions made available by the built-in controllers, see [[Functions]]. === Change Settings Method === If a method is of type "Change Settings", then a list of setting categories for the object referenced by the selected target node is displayed on the left side of the Method Info window. (Most nodes types have only one category.) Once a category is selected, the object's configurable settings are displayed in the list on the right side of the window. Any settings that are shown to be in an indeterminant state are not affected when the method is executed. All of the settings can be reset into the indeterminant state by clicking the Clear Settings button. === Evaluate Expression Method === If a method is of type "Evaluate Expression", then an expression can be entered in the Method Info window. See [[Expression Evaluation in Scripts]] for more information about expressions. == Variables == A script may define any number of variables, each having one of the following types. {| {{Table}} {{Tablehead|Type|Description}} |- {{Tablerow|'''boolean'''|The value true or false.}} |- {{Tablerow|'''integer'''|A 32-bit signed integer.}} |- {{Tablerow|'''float'''|A 32-bit floating-point number.}} |- {{Tablerow|'''string'''|A character string.}} |- {{Tablerow|'''color'''|A four-component RGBA color.}} |- {{Tablerow|'''vector'''|A three-dimensional vector.}} |- {{Tablerow|'''point'''|A three-dimensional point.}} |} A new variable is created by clicking the New button below the variable list on the left side of the Script Editor window. After clicking the New button, a dialog appears that lets you enter the following information about the new variable. * The variable name. A variable name can contain any of the characters A-Z, a-z, 0-9, or _ (underscore). A variable name cannot begin with a number. * The variable type. This can be any of the types listed above. * The variable scope. The scope can be Script, Object, or Controller. ** If a variable has the Script scope, then its value is reset to its initial value each time the script is run. ** If a variable has the Object scope, then it is shared among all instances of the node to which the script is attached and retains its value from one run to the next in a manner analogous to static local variables in C++. ** If a variable has the Controller scope, then it is stored in the controller for each instance of the node to which the script is attached and retains its value from one run to the next. Each instance has its own copy of the variable. * The variable's initial value. After a variable is created, it can be changed by double-clicking on it in the variable list. Whenever a variable is designated to receive the output value for a method, the name of the variable followed by an equals sign is displayed in the method's box in the script viewport. This gives a visual indication that the variable is being set to the value produced by the method. The output value of a method is implicitly converted to the type of the variable to which it is assigned, if necessary. The value of a variable is used as an input for a method by entering the variable's name under the “Input Variables” column for a particular setting in the Method Info box. If the variable's type does not match the expected type for the setting, then its value is implicitly converted to the needed type. == See Also == * [[Methods]] * [[Expression Evaluation in Scripts]] * [[Defining a Custom Method]] * [[Functions]] [[Category:Scripts]] 1fe83864490320e8ee09110167bc73fa77396dcc Methods 0 432 435 2023-07-15T12:02:02Z Eric Lengyel 1 Created page with "__NOTOC__ There are several types of script methods that are defined in the engine module. An application module can define any number of its own [[Defining a Custom Method|custom script methods]] as well, and they will show up in the palette on the left side of the script editor window. === Basic Methods === The following table describes the operation of the methods built into the engine that appear under the '''Basic''' in the [[Script Editor]]. {| {{Table}} {{Table..." wikitext text/x-wiki __NOTOC__ There are several types of script methods that are defined in the engine module. An application module can define any number of its own [[Defining a Custom Method|custom script methods]] as well, and they will show up in the palette on the left side of the script editor window. === Basic Methods === The following table describes the operation of the methods built into the engine that appear under the '''Basic''' in the [[Script Editor]]. {| {{Table}} {{Tablehead3|Method|Description|Duration}} |- {{Tablerow3|'''Null'''|Performs no operation. This method is useful for joining multiple fibers of execution at the end of a loop or as a starting node for the script when a loop begins at the first method that performs some action.|Completes immediately.}} |- {{Tablerow3|'''Evaluate&nbsp;Expression'''|Evaluates a text expression and outputs the result. For a description of expression syntax, see [[Expression Evaluation in Scripts]]. (If the expression contains a syntax error, then the method is colored bright yellow in the Script Editor.)|Completes immediately.}} |- {{Tablerow3|'''Call&nbsp;Controller&nbsp;Function'''|Calls a function of the controller attached to the method's target node. The specific settings depend on the purpose of the function itself.|Completes when the function indicates that is has finished what it's doing.}} |- {{Tablerow3|'''Change&nbsp;Settings'''|Changes one or more settings for the object referenced by the target node.|Completes immediately.}} |- {{Tablerow3|'''Activate&nbsp;Controller'''|Activates the controller attached to the method's target node. The effect depends on the controller being activated. In the case that the target node has a script controller attached to it, any scripts that handle the controller activate event are executed.|Completes immediately.}} |- {{Tablerow3|'''Deactivate&nbsp;Controller'''|Deactivates the controller attached to the method's target node. The effect depends on the controller being deactivated. In the case that the target node has a script controller attached to it, any scripts that handle the controller deactivate event are executed.|Completes immediately.}} |- {{Tablerow3|'''Set&nbsp;Color&nbsp;Value'''|Sets the red, green, blue, and alpha components of a color variable to specific values.|Completes immediately.}} |- {{Tablerow3|'''Set&nbsp;Vector&nbsp;Value'''|Sets the ''x'', ''y'', and ''z'' components of a vector or point variable to specific values.|Completes immediately.}} |- {{Tablerow3|'''Get&nbsp;External&nbsp;Variable'''|Retrieves the value of a specific variable belonging to the script controller attached to the target node of the method. This method is useful for reading values from other scripts in the world and storing them in variables local to the running script. If the variable being retrieved has object or controller scope, then its current value is returned, but if it has script scope, then its initial value is always returned.|Completes immediately.}} |- {{Tablerow3|'''Set&nbsp;External&nbsp;Variable'''|Sets the value of a specific variable belonging to the script controller attached to the target node of the method. This method is useful for copying values from variables local to the running script to object-scope or controller-scope variables of other scripts in the world. Only variables having object scope or controller scope can be modified using this method.|Completes immediately.}} |- {{Tablerow3|'''Get&nbsp;Script&nbsp;Time'''|Outputs the amount of time that has elapsed, as a floating-point value measured in seconds, since the script began running. The script time is updated once per frame. The time is guaranteed to be exactly 0.0 during the first frame in which the script is running.|Completes immediately.}} |- {{Tablerow3|'''Terminate&nbsp;External&nbsp;Script'''|Terminates all scripts running on the target node of the method. This method has no effect if the target node does not have a script controller attached to it. This method cannot be used to terminate the script containing the method itself, only scripts belonging to other nodes.|Completes immediately.}} |} === Standard Methods === The following table describes the operation of the methods built into the engine that appear under the '''Standard''' in the [[Script Editor]]. {| {{Table}} {{Tablehead3|Method|Description|Duration}} |- {{Tablerow3|'''Delay'''|Waits for a specified amount of time.|Completes after the specified time has elapsed.}} |- {{Tablerow3|'''Random&nbsp;Integer'''|Generates a random integer in a specified range and outputs the value. The boolean result is set to true if the value is not zero and false otherwise.|Completes immediately.}} |- {{Tablerow3|'''Random&nbsp;Float'''|Generates a random floating-point number in a specified range and outputs the value. The boolean result is set to true if the value is not zero and false otherwise. Note that in this case, a false result is extremely unlikely because the return value would have to be exactly 0.0.|Completes immediately.}} |- {{Tablerow3|'''Get&nbsp;String&nbsp;Length'''|Outputs the length of an input string.|Completes immediately.}} |- {{Tablerow3|'''Wake&nbsp;Controller'''|Awakens a controller.|Completes immediately.}} |- {{Tablerow3|'''Sleep&nbsp;Controller'''|Puts a controller to sleep.|Completes immediately.}} |- {{Tablerow3|'''Schedule&nbsp;Sleep'''|Tells a controller to go to sleep at the soonest convenient time. For most controllers, this method is equivalent to the Sleep Controller method. Some controllers may delay the sleep operation until a task has been completed, such as allowing an animation to finish playing.|Completes immediately.}} |- {{Tablerow3|'''Get&nbsp;Controller&nbsp;Wake&nbsp;State'''|Returns a boolean value indicating whether a controller is currently awake.|Completes immediately.}} |- {{Tablerow3|'''Enable&nbsp;Node'''|Enables its target node.|Completes immediately.}} |- {{Tablerow3|'''Disable&nbsp;Node'''|Disables its target node.|Completes immediately.}} |- {{Tablerow3|'''Get&nbsp;Node&nbsp;Enable&nbsp;State'''|Returns a boolean value indicating whether the target node is currently enabled.|Completes immediately.}} |- {{Tablerow3|'''Delete&nbsp;Node'''|Deletes its target node. It is possible to delete the node to which the script is attached (or any of its ancestors) with this method, but such a deletion is deferred until the end of the current frame.|Completes immediately.}} |- {{Tablerow3|'''Enable&nbsp;Interactivity'''|Enables interactivity for its target node.|Completes immediately.}} |- {{Tablerow3|'''Disable&nbsp;Interactivity'''|Disables interactivity for its target node.|Completes immediately.}} |- {{Tablerow3|'''Get&nbsp;Node&nbsp;Interactivity&nbsp;State'''|Returns a boolean value indicating whether the target node is currently interactive. If the target node does not possess the Interactivity property, then the return value is false.|Completes immediately.}} |- {{Tablerow3|'''Show&nbsp;Geometry'''|Shows the target node. Has no effect if the target is not a geometry node.|Completes immediately.}} |- {{Tablerow3|'''Hide&nbsp;Geometry'''|Hides the target node. Has no effect if the target is not a geometry node.|Completes immediately.}} |- {{Tablerow3|'''Get&nbsp;Geometry&nbsp;Visibility&nbsp;State'''|Returns a boolean value indicating whether the target node is visible. If the target node is not a geometry node, then the return value is false.|Completes immediately.}} |- {{Tablerow3|'''Activate&nbsp;Trigger'''|Activates a trigger. Has no effect if the target is not a trigger node. When a trigger node is activated, it searches for a controller to activate in the following order and performs exactly one of the following actions. # If the trigger node itself has a controller, then that controller is activated. # If the trigger object specifies an activation connector key, there is a node connected to the trigger through a connector having that key, and that node has a controller, then that controller is activated. # If such a target node exists, but it does not have a controller, then its immediate subnodes are examined. Every controller belonging to that set of subnodes is activated.|Completes immediately.}} |- {{Tablerow3|'''Deactivate&nbsp;Trigger'''|Deactivates a trigger. Has no effect if the target is not a trigger node. When a trigger node is deactivated, it searches for a controller to deactivate in the following order and performs exactly one of the following actions. # If the trigger node itself has a controller, then that controller is deactivated. # If the trigger object specifies a deactivation connector key, there is a node connected to the trigger through a connector having that key, and that node has a controller, then that controller is deactivated. # If such a target node exists, but it does not have a controller, then its immediate subnodes are examined. Every controller belonging to that set of subnodes is deactivated.|Completes immediately.}} |- {{Tablerow3|'''Break&nbsp;Joint'''|Breaks a joint. Has no effect if the target is not a joint node. If the joint node has a controller, then it is ''not'' activated as it would be if the joint were broken due to sufficient force being applied to it.|Completes immediately.}} |- {{Tablerow3|'''Remove&nbsp;Modifiers'''|Removes modifiers of a specific type, or all modifiers, from an instance node. Has no effect if the target is not an instance node. This method has no immediate effect, but the removed modifiers affect how the instanced world is loaded when a saved game is restored.|Completes immediately.}} |- {{Tablerow3|'''Get&nbsp;Object-Space&nbsp;Position'''|Returns a 3D point containing the object-space position of the target node.|Completes immediately.}} |- {{Tablerow3|'''Get&nbsp;World-Space&nbsp;Position'''|Returns a 3D point containing the world-space position of the target node.|Completes immediately.}} |- {{Tablerow3|'''Play&nbsp;Ambient&nbsp;Sound'''|Plays a sound resource without 3D spatialization.|Completes when the sound has finished playing.}} |- {{Tablerow3|'''Play&nbsp;Sound&nbsp;Source'''|Plays the target node. Has no effect if the target is not a source node.|If the source was already playing or the source is looping, then the method completes immediately. Otherwise, the method completes when the source finishes playing.}} |- {{Tablerow3|'''Stop&nbsp;Sound&nbsp;Source'''|Stops its target node. Has no effect if the target is not a source node.|Completes immediately.}} |- {{Tablerow3|'''Vary&nbsp;Source&nbsp;Volume'''|Varies the volume of its target node over a given amount of time. Has no effect if the target is not a source node.|Completes immediately.}} |- {{Tablerow3|'''Vary&nbsp;Source&nbsp;Frequency'''|Varies the frequency of its target node over a given amount of time. Has no effect if the target is not a source node.|Completes immediately.}} |- {{Tablerow3|'''Set&nbsp;Material&nbsp;Color'''|Changes the color of one of the material attributes assigned to its target node. Has no effect if the target is not a geometry node. Since materials are shared, all geometry nodes using the same material, not necessarily just the target, are affected. Thus, to change a material color for only one geometry node, it should use a unique material. This method can change any material attribute that includes a color, such as diffuse, specular, or emission. The mutable flag corresponding to the color must be checked under the Flags tab in the [[Material Editor]].|Completes immediately.}} |- {{Tablerow3|'''Set&nbsp;Shader&nbsp;Scalar&nbsp;Parameter'''|Changes the value of a Constant Scalar process in the shader assigned to its target node. Has no effect if the target is not a geometry node or if no material assigned to the geometry uses a custom shader. Since materials are shared, all geometry nodes using the same material, not necessarily just the target, are affected. Thus, to change a scalar parameter for only one geometry node, it should use a unique material.|Completes immediately.}} |- {{Tablerow3|'''Set&nbsp;Shader&nbsp;Vector&nbsp;Parameter'''|Changes the value of a Constant Vector process in the shader assigned to its target node. Has no effect if the target is not a geometry node or if no material assigned to the geometry uses a custom shader. Since materials are shared, all geometry nodes using the same material, not necessarily just the target, are affected. Thus, to change a vector parameter for only one geometry node, it should use a unique material.|Completes immediately.}} |- {{Tablerow3|'''Set&nbsp;Shader&nbsp;Color&nbsp;Parameter'''|Changes the value of a Constant Color process in the shader assigned to its target node. Has no effect if the target is not a geometry node or if no material assigned to the geometry uses a custom shader. Since materials are shared, all geometry nodes using the same material, not necessarily just the target, are affected. Thus, to change a color parameter for only one geometry node, it should use a unique material.|Completes immediately.}} |} === Event Methods === The following table describes the special methods that appear under the '''Events''' in the [[Script Editor]]. These methods each return a boolean value indicating whether the specific type of event was the one that initiated script execution. {| {{Table}} {{Tablehead3|Method|Description|Duration}} |- {{Tablerow3|'''Controller&nbsp;Activate&nbsp;Event'''|Returns a boolean value indicating whether the script was run to handle a controller activate event. This event can only occur for scripts attached to nodes.|Completes immediately.}} |- {{Tablerow3|'''Controller&nbsp;Deactivate&nbsp;Event'''|Returns a boolean value indicating whether the script was run to handle a controller deactivate event. This event can only occur for scripts attached to nodes.|Completes immediately.}} |- {{Tablerow3|'''Widget&nbsp;Activate&nbsp;Event'''|Returns a boolean value indicating whether the script was run to handle a widget activate event. This event can only occur for scripts attached to widgets.|Completes immediately.}} |- {{Tablerow3|'''Widget&nbsp;Change&nbsp;Event'''|Returns a boolean value indicating whether the script was run to handle a widget change event. This event can only occur for scripts attached to widgets.|Completes immediately.}} |- {{Tablerow3|'''Widget&nbsp;Begin&nbsp;Hover&nbsp;Event'''|Returns a boolean value indicating whether the script was run to handle a widget begin hover event. This event can only occur for scripts attached to widgets.|Completes immediately.}} |- {{Tablerow3|'''Widget&nbsp;End&nbsp;Hover&nbsp;Event'''|Returns a boolean value indicating whether the script was run to handle a widget end hover event. This event can only occur for scripts attached to widgets.|Completes immediately.}} |- {{Tablerow3|'''Script&nbsp;First&nbsp;Execution&nbsp;Event'''|Returns a boolean value indicating whether this is the first time a script has been executed for a particular script controller.|Completes immediately.}} |} == See Also == * [[Script Editor]] * [[Expression Evaluation in Scripts]] * [[Defining a Custom Method]] [[Category:Scripts]] ca87f28932e17133a9b6ab1244eddad3e9498fbc Expression Evaluation in Scripts 0 433 436 2023-07-15T12:03:18Z Eric Lengyel 1 Created page with "__NOTOC__ A [[Script Editor | script]] in the C4 Engine can contain methods of the type '''Evaluate Expression''', sometimes called an ''expression method'' for short. An expression method holds a text string representing a mathematical expression that gets evaluated when script execution reaches the method. For an expression method, a text box is displayed on the left side of the Method Info window where a textual expression may be entered. (The Method Info window is o..." wikitext text/x-wiki __NOTOC__ A [[Script Editor | script]] in the C4 Engine can contain methods of the type '''Evaluate Expression''', sometimes called an ''expression method'' for short. An expression method holds a text string representing a mathematical expression that gets evaluated when script execution reaches the method. For an expression method, a text box is displayed on the left side of the Method Info window where a textual expression may be entered. (The Method Info window is opened by selecting a method and then typing Ctrl-I.) A field for designating an output variable also appears in the lower-left corner of the Method Info window. If there is a syntax error in an expression, then the method is colored yellow in the script viewport. == Operators == Expressions can use any of the operators from the following list. They are listed in order of evaluation precedence, which matches the precedence rules for C++. Parentheses can be used to group subexpressions. {| {{Table}} {{Tablehead4|Operator|Description|Variable types accepted|Notes}} |- {{Tablerow4|<code>.</code>|'''Member Access'''|color, vector, point|Returns a scalar component of type float. For colors, one of <code>r</code>, <code>g</code>, <code>b</code>, or <code>a</code> can appear to the right of the dot operator. For vectors and points, one of <code>x</code>, <code>y</code>, or <code>z</code> can appear to the right of the dot operator.}} |- {{Tablerow4|<code>~</code>|'''Bitwise NOT'''|boolean, integer|This is a unary operator.}} |- {{Tablerow4|<code>*</code>|'''Multiply'''|boolean, integer, float, color, vector, point|Colors can only be multiplied by other colors or by floating-point, integer, or boolean scalar values. Vectors and points can only be multiplied by other vectors and points or by floating-point, integer, or boolean scalar values. Multiplication is componentwise for colors, vectors, and points.}} |- {{Tablerow4|<code>/</code>|'''Divide'''|boolean, integer, float, color, vector, point|A color, vector, or point type can only appear as the left operand, and they can be divided by floating-point, integer, or boolean scalar values. Integer division by zero is defined to be zero.}} |- {{Tablerow4|<code>%</code>|'''Modulo'''|boolean, integer|If the right operand is zero, then the result is defined to be zero.}} |- {{Tablerow4|<code>+</code>|'''Plus'''|boolean, integer, float, string, color, vector, point|Colors can only be added to other colors. Vectors and points can only be added to other vectors and points. A unary plus is accepted and performs no operation.}} |- {{Tablerow4|<code>&minus;</code>|'''Minus''' or '''Negate'''|boolean, integer, float, color, vector, point|Colors can only be subtracted from other colors. Vectors and points can only be subtracted from other vectors and points.}} |- {{Tablerow4|<code>&lt;&lt;</code>|'''Shift Left'''|boolean, integer|}} |- {{Tablerow4|<code>&gt;&gt;</code>|'''Shift Right'''|boolean, integer|The shift is always signed.}} |- {{Tablerow4|<code>&lt;</code>|'''Less Than'''|boolean, integer, float|Always returns a boolean result.}} |- {{Tablerow4|<code>&gt;</code>|'''Greater Than'''|boolean, integer, float|Always returns a boolean result.}} |- {{Tablerow4|<code>&lt;&#x3D;</code>|'''Less Than or Equal'''|boolean, integer, float|Always returns a boolean result.}} |- {{Tablerow4|<code>&gt;&#x3D;</code>|'''Greater Than or Equal'''|boolean, integer, float|Always returns a boolean result.}} |- {{Tablerow4|<code>&#x3D;&#x3D;</code>|'''Equal'''|boolean, integer, float, string|Always returns a boolean result.}} |- {{Tablerow4|<code>!&#x3D;</code>|'''Not Equal'''|boolean, integer, float, string|Always returns a boolean result.}} |- {{Tablerow4|<code>&amp;</code>|'''Bitwise AND'''|boolean, integer|}} |- {{Tablerow4|<code>^</code>|'''Bitwise XOR'''|boolean, integer|}} |- {{Tablerow4|<code>&#x7C;</code>|'''Bitwise OR'''|boolean, integer|}} |} Note that the logical operators <code>&&</code> and <code>||</code> are not present in the table. These were intentionally left out of the scripting language because they are not necessary. The same results can be attained by using the <code>&</code> and <code>|</code> operators instead. If the evaluation semantics of <code>&&</code> and <code>||</code> are needed, then you can use conditional execution to evaluate the expression in pieces. == Operands == Each operand in an expression can be any of the following: * The boolean value <code>true</code> or <code>false</code>. * An integer literal value using any features from the [http://openddl.org/ OpenDDL syntax]. This includes underscores separating digits, support for binary, octal, and hexadecimal literals (using the prefixes <code>0b</code>, <code>0o</code>, and <code>0x</code>, respectively), and character literals enclosed in single quotes. Integers are always stored as signed 32-bit quantities. * A floating-point literal value matching the OpenDDL syntax, with the exception that it must be decimal and contain one of the characters '<code>.</code>', '<code>e</code>', or '<code>E</code>' (decimal point or exponent indicator). Floats are always stored as 32-bit quantities. * A literal string matching the OpenDDL syntax. Escape characters and Unicode are supported. * The name of any variable defined for the script, possibly followed by the dot operator to access an individual component of a color, vector, or point. In any binary operation appearing in an expression, a mismatch between the types of the two operands causes one of the operands to be promoted to the type of the other. The possible promotions are those in the following list: * Boolean can be promoted to integer, float, or string. * Integer can be promoted to float or string. * Float can be promoted to string. == Result == An expression always produces an output value, and the boolean result for the expression method reflects the value of the expression. If the output value is not stored in a variable, then the boolean result is still valid. If the value of the expression is not boolean, then one of the following conversions is made to arrive at a boolean result: * For an integer, the value 0 becomes false, and any other value becomes true. * For a float, the value 0.0 becomes false, and any other value becomes true. * For a string, the empty string becomes false, and any other string becomes true. == Expression Grammar == The following grammar provides a formal description of exactly how expressions are parsed. <pre> identifier ::= [A-Za-z_] [0-9A-Za-z_]* hex-digit ::= [0-9A-Fa-f] escape-char ::= '\"' | "\'" | "\?" | "\\" | "\a" | "\b" | "\f" | "\n" | "\r" | "\t" | "\v" | "\x" hex-digit hex-digit bool-literal ::= "false" | "true" decimal-literal ::= [0-9] ("_"? [0-9])* hex-literal ::= ("0x" | "0X") hex-digit ("_"? hex-digit)* octal-literal ::= ("0o" | "0O") [0-7] ("_"? [0-7])* binary-literal ::= ("0b" | "0B") ("0" | "1") ("_"? ("0" | "1"))* char-literal ::= "'" ([#x20-#x26#x28-#x5B#x5D-#x7E] | escape-char)+ "'" integer-literal ::= decimal-literal | hex-literal | octal-literal | binary-literal | char-literal float-literal ::= (([0-9] ("_"? [0-9])* "." ([0-9] ("_"? [0-9])*)? | ([0-9] ("_"? [0-9])*)? "." [0-9] ("_"? [0-9])*) (("e" | "E") ("+" | "-")? [0-9] ("_"? [0-9])*)? | [0-9] ("_"? [0-9])* ("e" | "E") ("+" | "-")? [0-9] ("_"? [0-9])*) string-literal ::= ('"' ([#x20-#x21#x23-#x5B#x5D-#x7E#xA0-#xD7FF#xE000-#xFFFD#x010000-#x10FFFF] | escape-char | "\u" hex-digit hex-digit hex-digit hex-digit | "\U" hex-digit hex-digit hex-digit hex-digit hex-digit hex-digit)* '"')+ primary-expression ::= ("+" | "-" | "~")? (identifier ("." identifier)? | integer-literal | float-literal | string-literal | "(" or-expression ")") multiplicative-expression ::= (multiplicative-expression "*" | multiplicative-expression "/" | multiplicative-expression "%")? primary-expression additive-expression ::= (additive-expression "+" | additive-expression "-")? multiplicative-expression shift-expression ::= (shift-expression "<<" | shift-expression ">>")? additive-expression relational-expression ::= (relational-expression "<" | relational-expression ">" | relational-expression "<<" | relational-expression ">>")? shift-expression equality-expression ::= (equality-expression "==" | equality-expression "!=")? relational-expression and-expression ::= (and-expression "&")? equality-expression xor-expression ::= (xor-expression "^")? and-expression or-expression ::= (or-expression "|")? xor-expression </pre> == See Also == * [[Script Editor]] [[Category:Scripts]] dfc1439dcf078f1049f509a49028b71165e20edd Template:Tablehead4 10 434 437 2023-07-15T12:03:45Z Eric Lengyel 1 Created page with "| style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 24px 2px 6px;" | {{{1}}} | style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 6px 2px 6px;" | {{{2}}} | style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black;..." wikitext text/x-wiki | style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 24px 2px 6px;" | {{{1}}} | style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 6px 2px 6px;" | {{{2}}} | style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 6px 2px 6px;" | {{{3}}} | style="font-weight: bold; vertical-align: top; background-color: #80C8FF; border: solid 1px #444; border-bottom: solid 2px black; padding: 2px 6px 2px 6px;" | {{{4}}} 954ea12ff5a3c0a22428bbeb4aa7ac3034ca50a8 Template:Tablerow4 10 435 438 2023-07-15T12:04:07Z Eric Lengyel 1 Created page with "| style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 24px 2px 6px;" | {{{1}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{2}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{3}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{..." wikitext text/x-wiki | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 24px 2px 6px;" | {{{1}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{2}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{3}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{4}}} 7d7951ae1ed89f817ffcefa18a40641fc5d4e2d7 Category:Scripts 14 436 439 2023-07-15T12:04:22Z Eric Lengyel 1 Created blank page wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Panel Editor 0 437 440 2023-07-15T12:05:59Z Eric Lengyel 1 Created page with "[[File:Paneleditor.png|right|frame|'''Figure 1.''' The Panel Editor window.]] The '''Panel Editor''', shown in the image to the right, is a tool included with the C4 Engine that is used to create and edit graphical user interfaces of two different types. First, the panel editor can be used to create windows, dialogs, and heads-up displays that are rendered on top of a game on a two-dimensional desktop, and these interfaces are saved in individual panel resource files. Se..." wikitext text/x-wiki [[File:Paneleditor.png|right|frame|'''Figure 1.''' The Panel Editor window.]] The '''Panel Editor''', shown in the image to the right, is a tool included with the C4 Engine that is used to create and edit graphical user interfaces of two different types. First, the panel editor can be used to create windows, dialogs, and heads-up displays that are rendered on top of a game on a two-dimensional desktop, and these interfaces are saved in individual panel resource files. Second, the panel editor can be used to create interactive in-game interface panels that are saved as part of the world in which they exist. An interface panel is composed of a set of widgets, and many different types of widgets, including simple text and image widgets and more complex widgets like list boxes, are built into the engine. Custom widget subclasses can be defined in the game code and registered with the engine so they appear in the Panel Editor. Each widget can have one or more ''[[Mutators | mutators]]'' attached to it that produce animations of various kinds. Widgets belonging to in-game interface panels can also have scripts attached to them that get executed when the user interacts with the widgets. == Creating and Editing Panels == === Desktop Panel Resources === New panel resources can be created, and existing panel resources can be edited, by choosing the New Panel or Open Panel commands in the [[C4 Menu]]. The <code>panel</code> command can also be entered in the [[Command Console]] to open an existing panel resource. The dimensions, window title, and various flags for a desktop user interface panel are set by choosing Window Settings from the Panel menu. After saving the panel, the created <code>.pan</code> file can then be used in your game with the [http://c4engine.com/docs/InterfaceMgr/Window.html Window] class. === In-Game Panel Effects === An interface panel can be created in the World Editor by using the Panel Effect tool in the [[Effects Page]]. When a panel effect is selected, the Panel Editor can be opened for it by choosing &ldquo;Edit Script or Panel&rdquo; from the Node menu, which has the shortcut Ctrl-E. The Panel Editor is also accessible from the Controller pane in the Node Info window. The Panel Effect tool draws a rectangular region representing the boundary of the panel. When a panel is first created, it automatically has a Panel Controller assigned to it that can be accessed under the Controller pane in the Node Info window. An in-game panel possesses both its physical size in the world, as drawn with the Panel Effect tool, and an internal interface resolution. The resolution is adjusted in the properties for the Panel Controller. The interface resolution determines how big the virtual screen is on which items will be placed with the Panel Editor. Whatever resolution is chosen, the entire panel is fit precisely into the physical dimensions determined by the rectangle drawn in the World Editor. Thus, it's usually desirable to match the aspect ratios of both the panel's physical size and its interface resolution to avoid stretching the contents of the panel. Under the '''Panel''' tab in the Node Info window, there are three check boxes that affect how the panel is rendered. * The '''Apply depth offset''' flag causes the panel to be rendered with a small depth offset forward. This avoids z-fighting artifacts that could otherwise appear if a panel was drawn in the same plane as background geometry. * The '''Render two-sided''' flag causes the panel to be rendered regardless of on which side of the panel's plane the camera currently is. This lets the panel be seen from the back if it's drawn on a transparent surface or floating in mid-air. * The '''Render with fog''' flag allows fog to be rendered over a panel. This must be explicitly enabled in order for a panel to be rendered in a fogged environment. A panel effect can be made interactive by assigning the Interaction property to it under the Properties pane of the Node Info window. An interactive panel can display a cursor on top of the panel while the user is engaged with it. The cursor's texture image is specified in the panel controller's settings in the Node Info window. == Panel Editor Tools == There are eight tool buttons at the top of the Panel Editor window, and they have the following uses. In addition to clicking on the tool button, some of these tools can also be selected by pressing the number key shown in the table. {| {{Table}} {{Tablehead3|Icon|Shortcut|Function}} |- {{Tablerow3|[[File:Tool_select.png]]|1|'''Select Widgets'''. This tool can be used to safely select items without the possibility of accidentally moving them. To select a single widget inside a group instead of the group itself, hold in the Control key while clicking.}} |- {{Tablerow3|[[File:Tool_move.png]]|2|'''Move Widgets'''. Selects and moves widgets. Holding down the Shift key while moving constrains the movement to a single axis.}} |- {{Tablerow3|[[File:Tool_rotate.png]]|3|'''Rotate Widgets'''. Selects and rotates widgets. Click and drag a handle for a selected widget to rotate. Holding down the Shift key while rotating snaps the angle to 45 degree increments.}} |- {{Tablerow3|[[File:Tool_resize.png]]|4|'''Resize Widgets'''. Selects and resizes widgets. Click and drag a handle for a selected widget to resize. Holding down the Shift key while resizing constrains the proportional width and height.}} |- {{Tablerow3|[[File:Tool_texoffset.png]]||'''Offset Texture'''. Offsets the texture within the selected image widgets.}} |- {{Tablerow3|[[File:Tool_texscale.png]]||'''Scale Texture'''. Scales the texture within the selected image widgets.}} |- {{Tablerow3|[[File:Tool_scroll.png]]|6|'''Scroll'''. Scrolls the panel viewport. Holding down the Alt key temporarily selects the scroll tool.}} |- {{Tablerow3|[[File:Tool_zoom.png]]|7|'''Zoom'''. Zooms the panel viewport. Dragging vertically with this tool zooms in and out of a viewport. Using the mouse wheel with any other tool also zooms.}} |} == Pages == The following table describes the individual pages that are currently available in the Panel Editor. {| {{Table}} {{Tablehead|Page|Description}} |- {{Tablerow|[[File:Panel_widgets.png]]|'''Widgets'''. To place a new widget in the panel, select a type of widget from the list in this page and drag out a rectangle in the viewport.}} |- {{Tablerow|[[File:Panel_transform.png]]|'''Transform'''. This page allows you to enter the position, rotation angle, and size of a selected widget. The position and size are measured in pixels, and the rotation angle is measured in degrees.}} |- {{Tablerow|[[File:Panel_grid.png]]|'''Grid'''. The toggle buttons in this page control grid visibility and whether grid snapping is enabled.}} |} == Widget Settings == When one or more widgets are selected, their properties can be edited on the right side of the window. Different properties are shown depending on the types of the selected widgets, but all widgets have an identifier, a color, two flags indicating whether the widget is initially disabled or hidden, and settings for a help balloon. Settings that differ among multiple selected widgets are displayed in an indeterminate state until they are modified. See the [[Widgets | list of widgets]] for a description of the settings that are specific to each type of widget. === Common Settings === * The '''Widget identifier''' is a string of up to 15 characters used to identify widgets from C++ code or a script. It can be left blank for widgets that will not be referenced. This identifier does not need to be unique. When a script uses an identifier to operate on widgets in a panel, it affects all widgets within the panel having that same widget identifier. * The'''Widget color''' is the primary color used by a widget. The exact way in which this color is used depends on the type of the widget. * The '''Initially disabled''' check box indicates whether the widget is initially disabled so that it can't be clicked. * The '''Initially hidden''' check box indicates whether the item is initially hidden so that it isn't rendered. * The '''Balloon type''' menu specifies what kind of help balloon is assigned to the widget. * The '''Balloon string''' is a string that is interpreted based on the type of balloon. If the balloon type is a text string, then the balloon string is displayed directly in the help balloon for the widget. If the balloon type is a panel resource, then the balloon string is the name of the panel resource that gets loaded and displayed in the balloon. == Menu Commands == === Panel Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Close'''|Ctrl-W|Closes the panel editor window.}} |- {{Tablerow3|'''Save Panel'''|Ctrl-S|Saves the current panel.}} |- {{Tablerow3|'''Save Panel As...'''|Ctrl-Shift-S|Saves the current panel after prompting for a file name. (Available only for panel resources, not in-game panel effects.)}} |- {{Tablerow3|'''Window Settings...'''|Ctrl-P|Opens a dialog in which the window dimensions, its title, and various options can be set. (Panel resources only.)}} |} === Edit Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Undo'''|Ctrl-Z|Undoes the last action. (Supports multiple undo.)}} |- {{Tablerow3|'''Cut'''|Ctrl-X|Cuts the current selection to the clipboard.}} |- {{Tablerow3|'''Copy'''|Ctrl-C|Copies the current selection to the clipboard.}} |- {{Tablerow3|'''Paste'''|Ctrl-V|Pastes the contents of the clipboard to the panel.}} |- {{Tablerow3|'''Clear'''|Delete|Deletes the current selection.}} |- {{Tablerow3|'''Select All'''|Ctrl-A|Selects every widget in the panel.}} |- {{Tablerow3|'''Duplicate'''|Ctrl-D|Duplicates the selected widgets.}} |} === Widget Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Bring to Front'''|Ctrl-Shift-&#93;|Brings the selected widgets to the front so that they are rendered last.}} |- {{Tablerow3|'''Bring Forward'''|Ctrl-&#93;|Brings each selected widget forward ahead of the next widget that would be rendered.}} |- {{Tablerow3|'''Send Backward'''|Ctrl-&#91;|Sends each selected widget backward behind the previous widget that would be rendered.}} |- {{Tablerow3|'''Send to Bac'''k|Ctrl-Shift-&#91;|Sends the selected widgets to the back so that they are rendered first.}} |- {{Tablerow3|'''Hide Selection'''|Ctrl-H|Hides the selected widgets.}} |- {{Tablerow3|'''Unhide All'''|Ctrl-Shift-H|Shows all widgets in the panel.}} |- {{Tablerow3|'''Lock Selection'''|Ctrl-L|Locks the selected widgets so that they can no longer be selected.}} |- {{Tablerow3|'''Unlock All'''|Ctrl-Shift-L|Unlocks all widgets in the panel.}} |- {{Tablerow3|'''Group Selection'''|Ctrl-G|Groups the selected widgets. (No groups can be selected.)}} |- {{Tablerow3|'''Ungroup Selection'''|Ctrl-Shift-G|Ungroups the selected groups.}} |- {{Tablerow3|'''Reset Rotation'''|Ctrl-R|Removes any rotation from the selected widgets.}} |- {{Tablerow3|'''Reset Texcoords'''|Ctrl-T|Resets the texture coordinates for selected image widgets to the default values.}} |- {{Tablerow3|'''Auto-scale Texture'''|Ctrl-F|Scales, or &ldquo;fixes&rdquo;, the texture coordinates of selected image widgets so that the aspect ratio is 1:1.}} |- {{Tablerow3|'''Edit Script'''|Ctrl-E|Opens the script editor for the selected widget. (Available only for in-game panel effects.)}} |- {{Tablerow3|'''Delete Script'''||Removes any scripts from the selected widgets.}} |} === Arrange Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Nudge Left'''|Ctrl-Left|Nudges the selected widgets one pixel to the left.}} |- {{Tablerow3|'''Nudge Right'''|Ctrl-Right|Nudges the selected widgets one pixel to the right.}} |- {{Tablerow3|'''Nudge Up'''|Ctrl-Up|Nudges the selected widgets one pixel upward.}} |- {{Tablerow3|'''Nudge Down'''|Ctrl-Down|Nudges the selected widgets one pixel downward.}} |- {{Tablerow3|'''Align Left Sides'''|Ctrl-Shift-Left|Aligns the left sides of the selected widgets to the leftmost point in the selection.}} |- {{Tablerow3|'''Align Right Sides'''|Ctrl-Shift-Right|Aligns the right sides of the selected widgets to the rightmost point in the selection.}} |- {{Tablerow3|'''Align Top Sides'''|Ctrl-Shift-Up|Aligns the top sides of the selected widgets to the topmost point in the selection.}} |- {{Tablerow3|'''Align Bottom Sides'''|Ctrl-Shift-Down|Aligns the bottom sides of the selected widgets to the bottommost point in the selection.}} |- {{Tablerow3|'''Align Horizontal Centers'''||Aligns the horizontal centers of the selected widgets to the average between the leftmost and rightmost points in the selection.}} |- {{Tablerow3|'''Align Vertical Centers'''||Aligns the vertical centers of the selected widgets to the average between the topmost and bottommost points in the selection.}} |} == See Also == * [[Widgets]] * [[Sprockets]] * [[Slug Effects]] [[Category:Interface]] a1e19543c469ca5d9b38d81842f53b084464de10 File:Panel widgets.png 6 438 441 2023-07-15T12:06:13Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Panel transform.png 6 439 442 2023-07-15T12:06:26Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Panel grid.png 6 440 443 2023-07-15T12:06:41Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Text Formatting 0 441 444 2023-07-15T12:08:34Z Eric Lengyel 1 Created page with "Strings displayed by text widgets may contain the embedded formatting directives supported by [[Slug]]. A list of formatting directives begins with the two-character sequence '''{#''' and ends with the closing brace '''}'''. Each directive has the form '''directive(''params'')''', where ''params'' can be empty or consist of one or more parameters that apply to the directive. Multiple directives can be included in one list by separating them with semicolons. The followin..." wikitext text/x-wiki Strings displayed by text widgets may contain the embedded formatting directives supported by [[Slug]]. A list of formatting directives begins with the two-character sequence '''{#''' and ends with the closing brace '''}'''. Each directive has the form '''directive(''params'')''', where ''params'' can be empty or consist of one or more parameters that apply to the directive. Multiple directives can be included in one list by separating them with semicolons. The following table lists the formatting directives recognized by the [[Text Widget]]. {| {{Table}} {{Tablehead|Directive|Description}} |- {{Setting|'''size(''value'')'''|Set the font size to ''value'' in pixels, where ''value'' is a floating-point number. This directive is ignored if ''value'' is not greater than zero.}} |- {{Setting|'''stretch(''value'')'''|Set the text stretch to ''value'', where ''value'' is a floating-point number. Ignored if ''value'' is not greater than zero.}} |- {{Setting|'''track(''value'')'''|Set the text tracking to ''value'' in em units, where ''value'' is a floating-point number.}} |- {{Setting|'''skew(''value'')'''|Set the text skew to ''value'', where ''value'' is a floating-point number. Positive values skew to the right, and negative values skew to the left.}} |- {{Setting|'''scale(''x'', ''y'')'''|Set the text scale to (''x'', ''y''), where ''x'' and ''y'' are floating-point numbers. The ''y'' component may be omitted, in which case it is set equal to the ''x'' component. Ignored if either ''x'' or ''y'' is not greater than zero.}} |- {{Setting|'''offset(''x'', ''y'')'''|Set the text offset to (''x'', ''y'') in em units, where ''x'' and ''y'' are floating-point numbers. Positive values offset right and upward, and negative values offset left and downward.}} |- {{Setting|'''under(''value'')'''|Set the underline state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''strike(''value'')'''|Set the strikethrough state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''script(''value'')'''|Set the transform-based script state to ''value'', where ''value'' is an integer in the range [−3,&nbsp;3]. If ''value'' is 0, then the text scale and text offset states are set to the identity transform. If ''value'' is positive, then the superscript scale and offset are applied ''value'' times. If ''value'' is negative, then the subscript scale and offset are applied ''value'' times. Ignored if ''value'' is out of range or the font does not contain transform-based script information.}} |- {{Setting|'''left()'''|Set the text alignment to left. The new alignment takes effect at the beginning of the next line.}} |- {{Setting|'''right()'''|Set the text alignment to right. The new alignment takes effect at the beginning of the next line.}} |- {{Setting|'''center()'''|Set the text alignment to center. The new alignment takes effect at the beginning of the next line.}} |- {{Setting|'''lead(''value'')'''|Set the leading to ''value'' in em units, where ''value'' is a floating-point number. The new leading takes effect at the beginning of the next line.}} |- {{Setting|'''pspace(''value'')'''|Set the paragraph spacing to ''value'' in em units, where ''value'' is a floating-point number.}} |- {{Setting|'''margin(''left'',''right'')'''|Set the left and right paragraph margins to ''left'' and ''right'' in absolute units. The right margin may be omitted, in which case it is set to the same value as the left margin.}} |- {{Setting|'''indent(''value'')'''|Set the paragraph first-line indent to ''value'' in absolute units, where ''value'' is a floating-point number.}} |- {{Setting|'''kern(''value'')'''|Set the glyph kerning state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''mark(''value'')'''|Set the combining mark positioning state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''seq(''value'')'''|Set the sequence replacement state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''alt(''value'')'''|Set the alternate substitution state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''grid(''value'')'''|Set the grid positioning state to ''value'', where value is either '''true''' or '''false'''.}} |- {{Setting|'''color(''red'',''green'',''blue'',''alpha'')'''|Set the primary text color to (<i>red</i>, <i>green</i>, <i>blue</i>, <i>alpha</i>), where each component is an integer in the range [0,&#x202F;255]. The <i>alpha</i> component may be omitted, in which case it is 255. This directive is ignored if any component is out of range.}} |- {{Setting|'''color2(''red'',''green'',''blue'',''alpha'')'''|Set the secondary text color to (<i>red</i>, <i>green</i>, <i>blue</i>, <i>alpha</i>) using the same format as the primary color. The secondary text color is used only when gradients are enabled.}} |- {{Setting|'''gcoord(''y1'',''y2'')'''|Set the gradient coordinates to ''y1'' and ''y2''. These are the distances above the baseline at which the gradient is equal to the primary and secondary color, respectively. Negative values are allowed.}} |- {{Setting|'''grad(''value'')'''|Set the gradient state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''effect_color(''red'',''green'',''blue'',''alpha'')'''|Set the primary effect color to (<i>red</i>, <i>green</i>, <i>blue</i>, <i>alpha</i>), where each component is an integer in the range [0,&#x202F;255]. The <i>alpha</i> component may be omitted, in which case it is 255. This directive is ignored if any component is out of range.}} |- {{Setting|'''effect_color2(''red'',''green'',''blue'',''alpha'')'''|Set the secondary effect color to (<i>red</i>, <i>green</i>, <i>blue</i>, <i>alpha</i>) using the same format as the primary color. The secondary effect color is used only when effect gradients are enabled.}} |- {{Setting|'''effect_gcoord(''y1'',''y2'')'''|Set the effect gradient coordinates to ''y1'' and ''y2''. These are the distances above the baseline at which the gradient is equal to the primary and secondary color, respectively. Negative values are allowed.}} |- {{Setting|'''effect_grad(''value'')'''|Set the effect gradient state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''reset()'''|Reset all formatting state to the initial values given by the text widget. This directive always turns subscript and superscript modes off and resets their parameters to the default values.}} |} When sequence replacement is enabled, the following directives can be used to control what types of sequences are recognized. {| {{Table}} {{Tablehead|Directive|Description}} |- {{Setting|'''comp(''value'')'''|Set the glyph composition state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''slig(''value'')'''|Set the standard ligatures state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''rlig(''value'')'''|Set the required ligatures state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''dlig(''value'')'''|Set the discretionary ligatures state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''hlig(''value'')'''|Set the historical ligatures state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |} When alternate substitution is enabled, the following directives can be used to control what types of alternates are applied. {| {{Table}} {{Tablehead|Directive|Description}} |- {{Setting|'''style(''value'')'''|Set the stylistic alternates state to ''value'', where ''value'' is an integer in the range 0&ndash;20. If ''value'' is nonzero, stylistic alternates are enabled, and they use the set specified by ''value''. If ''value'' is zero, stylistic alternates are disabled. Ignored if ''value'' is out of range.}} |- {{Setting|'''historical(''value'')'''|Set the historical alternates state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''smallcap(''value'')'''|Set the lowercase small caps state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''capsmall(''value'')'''|Set the uppercase small caps state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''titling(''value'')'''|Set the titling caps state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''unicase(''value'')'''|Set the unicase state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''caseform(''value'')'''|Set the case-sensitive forms state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''slashzero(''value'')'''|Set the slashed zero state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''hyphenminus(''value'')'''|Set the hyphen minus state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''frac(''value'')'''|Set the fraction state to ''value'', where ''value'' is either '''true''' or '''false'''.}} |- {{Setting|'''lining(''value'')'''|Set the lining figures state to ''value'', where ''value'' is either '''true''' or '''false'''. If ''value'' is '''true''', then the oldstyle figures state is disabled.}} |- {{Setting|'''oldstyle(''value'')'''|Set the oldstyle figures state to ''value'', where ''value'' is either '''true''' or '''false'''. If ''value'' is '''true''', then the lining figures state is disabled.}} |- {{Setting|'''tabfig(''value'')'''|Set the tabular figures state to ''value'', where ''value'' is either '''true''' or '''false'''. If ''value'' is '''true''', then the proportional figures state is disabled.}} |- {{Setting|'''propfig(''value'')'''|Set the proportional figures state to ''value'', where ''value'' is either '''true''' or '''false'''. If ''value'' is '''true''', then the tabular figures state is disabled.}} |- {{Setting|'''sub(''value'')'''|Set the subscript state to ''value'', where ''value'' is either '''true''' or '''false'''. If ''value'' is '''true''', then the superscript, scientific inferiors, and ordinals states are disabled.}} |- {{Setting|'''sup(''value'')'''|Set the superscript state to ''value'', where ''value'' is either '''true''' or '''false'''. If ''value'' is '''true''', then the subscript, scientific inferiors, and ordinals states are disabled.}} |- {{Setting|'''inf(''value'')'''|Set the scientific inferiors state to ''value'', where ''value'' is either '''true''' or '''false'''. If ''value'' is '''true''', then the subscript, superscript, and ordinals states are disabled.}} |- {{Setting|'''ord(''value'')'''|Set the ordinals state to ''value'', where ''value'' is either '''true''' or '''false'''. If ''value'' is '''true''', then the subscript, superscript, and scientific inferiors states are disabled.}} |} == Examples == The chemical formula for water would be displayed using the following string. H{#sub(true)}2{#sub(false)}O Words can be displayed in different colors with the following string. {#color(255,0,0)}RED {#color(0,255,0)}GREEN {#color(0,0,255)}BLUE Text can be displayed at different sizes and with different tracking with the following string. Normal size {#size(30);track(0.2)} Big and wide == See Also == * [[Text Widget]] [[Category:Interface]] 8f49bf1d7f55e3a3123f12fa5edb613364d1a4d6 Slug 0 442 445 2023-07-15T12:09:13Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Slug.png|right]] The Slug Library is a product developed by Terathon Software for rendering high-quality, resolution-independent text and vector graphics in 3D applications on the GPU. It is used to render all text and icons in the C4 Engine. Detailed information can be found on the [http://sluglibrary.com/ Slug website]. == See Also == * [[Text Widget]] * [[Slug Effects]]" wikitext text/x-wiki __NOTOC__ [[File:Slug.png|right]] The Slug Library is a product developed by Terathon Software for rendering high-quality, resolution-independent text and vector graphics in 3D applications on the GPU. It is used to render all text and icons in the C4 Engine. Detailed information can be found on the [http://sluglibrary.com/ Slug website]. == See Also == * [[Text Widget]] * [[Slug Effects]] 59d5739b7087c94b7faf9d61616bd3c14b28496e Atmosphere Page 0 443 446 2023-07-15T12:11:05Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_atmosphere.png|right|frame|'''Figure 1.''' The Atmosphere Page.]] The '''Atmosphere Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. The Atmosphere Page contains tools for creating the following types of nodes. * [[Fog Spaces | Fog Space]] * [[Skyboxes | Skybox]] == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_atmosphere.png|right|frame|'''Figure 1.''' The Atmosphere Page.]] The '''Atmosphere Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. The Atmosphere Page contains tools for creating the following types of nodes. * [[Fog Spaces | Fog Space]] * [[Skyboxes | Skybox]] == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] f62e0829904feaac1290168dc73d13855abfb848 Category:Editor 14 444 447 2023-07-15T12:11:17Z Eric Lengyel 1 Created blank page wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Effects Page 0 445 448 2023-07-15T12:12:01Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_effects.png|right|frame|'''Figure 1.''' The Effects Page.]] The '''Effects Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. The Effects Page contains tools for creating the following types of effect nodes. * [[Quad Effect]] * [[Flare Effect]] * [[Beam Effect]] * [[Tube Effect]] * [[Fire Effect]] * [[Halo Effect]] * [[Shaft Effects]] * [[Slug Effects]] Panel effects can also be created using the tool in..." wikitext text/x-wiki __NOTOC__ [[File:Editor_effects.png|right|frame|'''Figure 1.''' The Effects Page.]] The '''Effects Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. The Effects Page contains tools for creating the following types of effect nodes. * [[Quad Effect]] * [[Flare Effect]] * [[Beam Effect]] * [[Tube Effect]] * [[Fire Effect]] * [[Halo Effect]] * [[Shaft Effects]] * [[Slug Effects]] Panel effects can also be created using the tool in the Effects Page. These can be opened and edited in the [[Panel Editor]]. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] a66860b21a03de896766c4f5a0bd3d2e8da68471 Shaft Effects 0 446 449 2023-07-15T12:14:32Z Eric Lengyel 1 Created page with "[[File:Shafts.jpg|right|frame|'''Figure 1.''' Shaft effects in a dungeon.]] A '''shaft effect''' renders a volumetric light shaft in a particular direction like those shown in Figure 1. There are four types of shaft effect (box, cylinder, truncated pyramid, and truncated cone) that can be created in the [[World Editor]] by using the tools in the [[Effects Page]]. A shaft effect is rendered with a volumetric light in-scattering shader that calculates the actual distance..." wikitext text/x-wiki [[File:Shafts.jpg|right|frame|'''Figure 1.''' Shaft effects in a dungeon.]] A '''shaft effect''' renders a volumetric light shaft in a particular direction like those shown in Figure 1. There are four types of shaft effect (box, cylinder, truncated pyramid, and truncated cone) that can be created in the [[World Editor]] by using the tools in the [[Effects Page]]. A shaft effect is rendered with a volumetric light in-scattering shader that calculates the actual distance travelled through the light shaft by a ray starting at the camera position for each pixel covered on the screen and determines how much light is scattered toward the viewer. Even though each type of light shaft has a finite extent in the scene, the interior is rendered as if the light shaft had infinite extent along the object-space ''z'' axis. For the box and cylinder shaft effects, the interior volume extends to infinity in both the positive and negative ''z'' directions. For the truncated pyramid and truncated cone light shafts, the interior volume extends to the apex of the untruncated volume in the positive ''z'' direction and to infinity in the negative ''z'' direction. The density at bottom end is often set to zero to give a light shaft the appearance of fading out and having only finite extent. Shaft effects have some basic animation controls described below that can be used to smoothly fade them between different intensity scales. == Shaft Effect Settings == A shaft effect can be configured under the '''Shaft''' tab in the Node Info window. The specific settings are described in the following table. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Shaft&nbsp;Settings'''|}} |- {{Tablerow|'''Shaft&nbsp;color'''|The color of the shaft effect. This should generally be a bright color, and the overall intensity of the light shaft should be controlled by the intensity scale.}} |- {{Tablerow|'''Density&nbsp;at&nbsp;bottom&nbsp;end'''|The density of the shaft at the bottom end (toward the &minus;''z'' direction).}} |- {{Tablerow|'''Density&nbsp;at&nbsp;top&nbsp;end'''|The density of the shaft at the top end (toward the +''z'' direction).}} |- {{Tablerow|'''Primary&nbsp;intensity&nbsp;scale'''|The primary scale factor by which the distance light travels through the shaft is multiplied to arrive at a final intensity value.}} |- {{Tablerow|'''Render&nbsp;width&nbsp;random&nbsp;noise'''|Causes the shaft effect to be rendered with a small amount of random noise in order to hide banding artifacts that can be visible against plain backgrounds or when shafts are animating their intensities. It is slightly more expensive to use random noise, so this option should be left unchecked if banding artifacts are not visible.}} |- {{Tablerow|'''Cull&nbsp;if&nbsp;camera&nbsp;above&nbsp;top&nbsp;plane'''|Indicates that the shaft effect should not be rendered if the camera is positioned above the top plane of the shaft's volumetric shape plus the margin given by the next setting, in object coordinates. This is useful when a shaft effect is placed at an opening like a window so that the shaft can only be seen from the inside of a structure.}} |- {{Tablerow|'''Top&nbsp;plane&nbsp;cull&nbsp;margin'''|Specifies a distance that is added to the maximum ''z'' value occupied by the shaft's volumetric shape in object coordinates when testing the camera position in the case that top plane culling is enabled by the previous setting.}} |- {{HeadingSetting|'''Shaft&nbsp;Animation&nbsp;Settings'''|}} |- {{Tablerow|'''Randomly&nbsp;animate&nbsp;intensity'''|Enables random intensity animation. The following settings control how the light shaft is animated.}} |- {{Tablerow|'''Secondary&nbsp;intensity&nbsp;scale'''|A secondary intensity scale that specifies the limit of the animation opposite the primary intensity scale above. The shaft effect intensity is smoothly animated between the primary and secondary intensities.}} |- {{Tablerow|'''Minimum&nbsp;primary&nbsp;hold&nbsp;time&nbsp;(s)'''|The minimum time, in seconds, for which the intensity is held at the primary level during animation. Whenever the shaft effect animation reaches the primary intensity, it selects a random time between this setting and the next setting and waits for that time before transitioning to the secondary intensity again.}} |- {{Tablerow|'''Maximum&nbsp;primary&nbsp;hold&nbsp;time&nbsp;(s)'''|The maximum time, in seconds, for which the intensity is held at the primary level during animation.}} |- {{Tablerow|'''Minimum&nbsp;secondary&nbsp;hold&nbsp;time&nbsp;(s)'''|The minimum time, in seconds, for which the intensity is held at the secondary level during animation. Whenever the shaft effect animation reaches the secondary intensity, it selects a random time between this setting and the next setting and waits for that time before transitioning to the primary intensity again.}} |- {{Tablerow|'''Maximum&nbsp;secondary&nbsp;hold&nbsp;time&nbsp;(s)'''|The maximum time, in seconds, for which the intensity is held at the secondary level during animation.}} |- {{Tablerow|'''Minimum&nbsp;transition&nbsp;time&nbsp;(s)'''|The minimum time, in seconds, over which the intensity transitions from the primary to secondary intensity level or vice-versa. Whenever the light shaft animation has finished holding at either the primary or secondary intensity scale, it selects a random time between this setting and the next setting and animates to the opposite extreme over that amount of time.}} |- {{Tablerow|'''Maximum&nbsp;transition&nbsp;time&nbsp;(s)'''|The maximum time, in seconds, over which the intensity transitions from the primary to secondary intensity level or vice-versa.}} |} == See Also == * [[Effects Page]] * [[Halo Effect]] 53c34e9abf2c6aa73d3c6b5df14ff59898398a45 Halo Effect 0 447 450 2023-07-15T12:15:05Z Eric Lengyel 1 Created page with "A '''halo effect''' renders a volumetric halo around a central point. It can be created in the [[World Editor]] by using the Halo Effect tool in the [[Effects Page]]. == Halo Effect Settings == A halo effect can be configured under the '''Halo''' tab in the Node Info window. The specific settings are described in the following table. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Halo&nbsp;Settings'''|}} |- {{Tablerow|'''Halo&nbsp;color'''|The c..." wikitext text/x-wiki A '''halo effect''' renders a volumetric halo around a central point. It can be created in the [[World Editor]] by using the Halo Effect tool in the [[Effects Page]]. == Halo Effect Settings == A halo effect can be configured under the '''Halo''' tab in the Node Info window. The specific settings are described in the following table. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Halo&nbsp;Settings'''|}} |- {{Tablerow|'''Halo&nbsp;color'''|The color of the halo effect.}} |- {{Tablerow|'''Intensity&nbsp;scale'''|The overall intensity of the halo effect. This has a multiplicative effect on the halo color.}} |- {{Tablerow|'''Render&nbsp;width&nbsp;random&nbsp;noise'''|Specifies whether random noise is added to the halo effect. This is useful for eliminating banding artifacts.}} |} == See Also == * [[Effects Page]] * [[Shaft Effects]] 23ea612e5df3e5a7bbc008063f11093e08956f3f Quad Effect 0 448 451 2023-07-15T12:16:22Z Eric Lengyel 1 Created page with "A '''quad effect''' renders a billboarded quad around a central point. It can be created in the [[World Editor]] by using the Quad Effect tool in the [[Effects Page]]. == Quad Effect Settings == A quad effect can be configured under the '''Quad''' tab in the Node Info window. The specific settings are described in the following table. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Quad&nbsp;Settings'''|}} |- {{Tablerow|'''Quad&nbsp;color'''|The..." wikitext text/x-wiki A '''quad effect''' renders a billboarded quad around a central point. It can be created in the [[World Editor]] by using the Quad Effect tool in the [[Effects Page]]. == Quad Effect Settings == A quad effect can be configured under the '''Quad''' tab in the Node Info window. The specific settings are described in the following table. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Quad&nbsp;Settings'''|}} |- {{Tablerow|'''Quad&nbsp;color'''|The color of the quad effect.}} |- {{Tablerow|'''Texture&nbsp;map&nbsp;name'''|The name of the texture map applied to the quad. This texture map is multiplied by the quad color. The alpha channel of the texture map should be zero at the edges to avoid a visible boundary.}} |- {{Tablerow|'''Blend&nbsp;mode'''|Specifies the alpha blending mode to use. This can be one of the following values: * '''Add'''. The quad is added to the background. * '''Alpha add'''. The quad color is multiplied by its alpha value and then added to the background. * '''Alpha blend'''. The quad color is multiplied by its alpha value and then added to the background multiplied by the complement of the alpha value. * '''Add preblend'''. The quad color is directly added to the background multiplied by the complement of the alpha value. * '''Replace'''. The quad color replaces the background without any alpha blending.}} |- {{Tablerow|'''Render&nbsp;with&nbsp;fog'''|Specifies whether fog is applied to the quad effect.}} |- {{Tablerow|'''Render&nbsp;at&nbsp;infinity'''|If checked, the quad effect is rendered at infinity in the direction of its &minus;''z'' axis. In this case, the position of the quad effect node has no meaning.}} |- {{Tablerow|'''Render&nbsp;with&nbsp;soft&nbsp;depth'''|Specifies that the quad effect should account for the depth of geometry in the scene and fade out as it gets close to opaque surfaces. This eliminates hard edges due to Z buffering.}} |- {{Tablerow|'''Soft&nbsp;depth&nbsp;scale'''|If soft depth rendering is enabled, this specifies the amount by which the difference in depth between the quad effect and the background geometry is scaled. Lower values correspond to a softer fade out.}} |} == See Also == * [[Effects Page]] b1b72dea1e32478fdf4bd48747fd6b1c721dfa47 Beam Effect 0 449 452 2023-07-15T12:16:41Z Eric Lengyel 1 Created page with "A '''beam effect''' renders a polyboarded quad around a central axis. It can be created in the [[World Editor]] by using the Beam Effect tool in the [[Effects Page]]. A beam effect is similar to a [[Quad Effect|quad effect]], with the difference being that the beam rotates about its ''z'' axis where the quad rotates about its origin position. == Beam Effect Settings == A beam effect can be configured under the '''Beam''' tab in the Node Info window. The specific settin..." wikitext text/x-wiki A '''beam effect''' renders a polyboarded quad around a central axis. It can be created in the [[World Editor]] by using the Beam Effect tool in the [[Effects Page]]. A beam effect is similar to a [[Quad Effect|quad effect]], with the difference being that the beam rotates about its ''z'' axis where the quad rotates about its origin position. == Beam Effect Settings == A beam effect can be configured under the '''Beam''' tab in the Node Info window. The specific settings are described in the following table. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Beam&nbsp;Settings'''|}} |- {{Tablerow|'''Beam&nbsp;color'''|The color of the beam effect.}} |- {{Tablerow|'''Texture&nbsp;map&nbsp;name'''|The name of the texture map applied to the beam. This texture map is multiplied by the beam color. The alpha channel of the texture map should be zero at the left and right edges to avoid a visible boundary.}} |- {{Tablerow|'''Texture&nbsp;coordinate&nbsp;scale'''|Specifies the number of times that the texture map is repeated in the vertical direction over the length of the beam effect.}} |- {{Tablerow|'''Render&nbsp;with&nbsp;soft&nbsp;depth'''|Specifies that the beam effect should account for the depth of geometry in the scene and fade out as it gets close to opaque surfaces. This eliminates hard edges due to Z buffering.}} |- {{Tablerow|'''Soft&nbsp;depth&nbsp;scale'''|If soft depth rendering is enabled, this specifies the amount by which the difference in depth between the beam effect and the background geometry is scaled. Lower values correspond to a softer fade out.}} |} == See Also == * [[Effects Page]] 34b04d5ca6b0b99dcc2c0e38f3abbd31975fc8c7 Flare Effect 0 450 453 2023-07-15T12:17:06Z Eric Lengyel 1 Created page with "A '''flare effect''' renders a billboarded flare around a central point. It can be created in the [[World Editor]] by using the Flare Effect tool in the [[Effects Page]]. The difference between a flare effect and a [[Quad Effect|quad effect]] is that the flare effect does not use depth testing, but instead uses an occlusion query to determine how bright it is. == Flare Effect Settings == A flare effect can be configured under the '''Flare''' tab in the Node Info window..." wikitext text/x-wiki A '''flare effect''' renders a billboarded flare around a central point. It can be created in the [[World Editor]] by using the Flare Effect tool in the [[Effects Page]]. The difference between a flare effect and a [[Quad Effect|quad effect]] is that the flare effect does not use depth testing, but instead uses an occlusion query to determine how bright it is. == Flare Effect Settings == A flare effect can be configured under the '''Flare''' tab in the Node Info window. The specific settings are described in the following table. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Flare&nbsp;Settings'''|}} |- {{Tablerow|'''Flare&nbsp;color'''|The color of the flare effect.}} |- {{Tablerow|'''Texture&nbsp;map&nbsp;name'''|The name of the texture map applied to the flare. This texture map is multiplied by the flare color. The alpha channel of the texture map should be zero at the edges to avoid a visible boundary.}} |- {{Tablerow|'''Occlusion&nbsp;radius'''|Specifies the radius of the occlusion quad that's rendered before the flare to determine how bright the flare is. The brightness of the flare rendered later is proportional to the visible area of this occlusion quad.}} |- {{Tablerow|'''Rotation&nbsp;radius'''|Specifies the radius of the sphere on which the occlusion quad is rendered. This causes the occlusion quad to be offset from the center of the flare effect so that geometry near the center does not interfere with the occlusion test.}} |- {{Tablerow|'''Render&nbsp;with&nbsp;fog'''|Specifies whether fog is applied to the flare effect.}} |- {{Tablerow|'''Render&nbsp;at&nbsp;infinity'''|If checked, the flare effect is rendered at infinity in the direction of its &minus;''z'' axis. In this case, the position of the flare effect node has no meaning.}} |} == See Also == * [[Effects Page]] fdb100ad2120b70621a2e94b942e7bb4513e5c7e Find Page 0 451 454 2023-07-15T12:17:55Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_find.png|right|frame|'''Figure 1.''' The Find Page.]] The '''Find Page''' is a tool page in the [[World Editor]]. It can be found under the '''Editor''' tab. The controls in the Find Page can be used to select nodes in the world using search criteria such as the node's name, the node's type, and the type of controller attached to the node. If the '''Name''' box is not empty, then only nodes having the exact name entered, but without case sensiti..." wikitext text/x-wiki __NOTOC__ [[File:Editor_find.png|right|frame|'''Figure 1.''' The Find Page.]] The '''Find Page''' is a tool page in the [[World Editor]]. It can be found under the '''Editor''' tab. The controls in the Find Page can be used to select nodes in the world using search criteria such as the node's name, the node's type, and the type of controller attached to the node. If the '''Name''' box is not empty, then only nodes having the exact name entered, but without case sensitivity, are matched. If the '''Type''' box is checked, then only nodes having one of the selected types are matched. Multiple node types may be selected at once by using shift-click or control-click. If the '''Controller''' box is checked, then only nodes with a controller having one of the selected types are matched. Multiple controller types may be selected. The '''Find All''' button selects all nodes in the world that match the search criteria. The '''Find Next''' and '''Find Prev''' buttons change the selection to the next and previous nodes in the scene graph that match the search criteria. In the case that no nodes have been selected yet, the '''Find Next''' and '''Find Prev''' buttons select the first and last matching nodes, respectively. Note that nodes belonging to instanced worlds are never selected. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] 0d161c5631b10f555664b0b14a7ade9a880bebb8 Geometries Page 0 452 455 2023-07-15T12:18:27Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_geometries.png|right|frame|'''Figure 1.''' The Geometries Page.]] The '''Geometries Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_geometries.png|right|frame|'''Figure 1.''' The Geometries Page.]] The '''Geometries Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] 700737ba5d506ce9be77d67ff01b33070ea8bd94 Grid Page 0 453 456 2023-07-15T12:18:48Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_grid.png|right|frame|'''Figure 1.''' The Grid Page.]] The '''Grid Page''' is a tool page in the [[World Editor]]. It can be found under the '''Editor''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_grid.png|right|frame|'''Figure 1.''' The Grid Page.]] The '''Grid Page''' is a tool page in the [[World Editor]]. It can be found under the '''Editor''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] 2b4a9bfd70bfad5580772bf61caf8d9109b026c6 Impostors 0 454 457 2023-07-15T12:19:10Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_impostors.png|right|frame|'''Figure 1.''' The Impostors Page.]] The '''Impostors Page''' is a tool page in the [[World Editor]]. It can be found under the '''Instance''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_impostors.png|right|frame|'''Figure 1.''' The Impostors Page.]] The '''Impostors Page''' is a tool page in the [[World Editor]]. It can be found under the '''Instance''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] 060cf5d6f78d0518b9a3f030917f18ce0174ec1e Info Page 0 455 458 2023-07-15T12:20:27Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_info.png|right|frame|'''Figure 1.''' The Info Page.]] The '''Info Page''' is a tool page in the [[World Editor]]. It can be found under the '''Editor''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_info.png|right|frame|'''Figure 1.''' The Info Page.]] The '''Info Page''' is a tool page in the [[World Editor]]. It can be found under the '''Editor''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] 8930a5e83ac61289c05094a6014ef699f44cbcce Landscaping Page 0 456 459 2023-07-15T12:20:50Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_landscaping.png|right|frame|'''Figure 1.''' The Landscaping Page.]] The '''Landscaping Page''' is a tool page in the [[World Editor]]. It can be found under the '''Earth''' tab, and it is used to manage landscaping brushes and paint landscaping on the terrain. == Managing Landscaping Brushes == The popup menu in the upper-right corner of the page contains the commands used to manage landscaping brushes. Each command is described in the following..." wikitext text/x-wiki __NOTOC__ [[File:Editor_landscaping.png|right|frame|'''Figure 1.''' The Landscaping Page.]] The '''Landscaping Page''' is a tool page in the [[World Editor]]. It can be found under the '''Earth''' tab, and it is used to manage landscaping brushes and paint landscaping on the terrain. == Managing Landscaping Brushes == The popup menu in the upper-right corner of the page contains the commands used to manage landscaping brushes. Each command is described in the following table. {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|'''New&nbsp;Landscaping&nbsp;Brush'''|Opens the [[Landscaping Editor]] with a new empty brush after displaying a dialog box to let you give it a name.}} |- {{Tablerow|'''Delete&nbsp;Landscaping&nbsp;Brush'''|Deletes the selected landscaping brush.}} |- {{Tablerow|'''Edit&nbsp;Landscaping&nbsp;Brush'''|Opens the [[Landscaping Editor]] to edit the selected landscaping brush.}} |- {{Tablerow|'''Duplicate&nbsp;Landscaping&nbsp;Brush'''|Duplicates the selected landscaping brush and displays a dialog box to let you give a name to the new copy.}} |- {{Tablerow|'''Rename&nbsp;Landscaping&nbsp;Brush'''|Displays a dialog box to let you change the name of the selected landscaping brush.}} |- {{Tablerow|'''Copy&nbsp;Landscaping&nbsp;Brush'''|Copies the selected landscaping brush to the clipboard.}} |- {{Tablerow|'''Pastes&nbsp;Landscaping&nbsp;Brush'''|Pastes the landscaping brush from the clipboard and displays a dialog box to let you give it a name.}} |} == Painting with Landscaping Brushes == The '''Additive Brush''' and '''Subtractive Brush''' tools can both be used to paint landscaping on the terrain using the currently selected landscaping brush, and they both attempt to change the density of the landscaping to match the '''Master Density''' setting. The additive brush does this by adding new instances to the world, and the subtractive brush does this by removing instances from the world. The '''Brush Radius''' setting controls the size of the landscaping brush. When the additive brush or subtractive brush tool is selected, a circle having this radius is projected onto the ground when the cursor is inside the perspective viewport. When instances belonging to a landscaping brush are added to the world with the landscaping tools, they are never placed in such a way that they intersect other objects that don't belong to the landscaping brush. The small display below the list of landscaping brushes shows green pixels where instances belonging to the brush were detected and red pixels where external objects were detected. == See Also == * [[Landscaping Editor]] * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] ba5a2a8b131bee3ff7a81b6871bd5d025f85d15c Lights Page 0 457 460 2023-07-15T12:21:20Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_lights.png|right|frame|'''Figure 1.''' The Lights Page.]] The '''Lights Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_lights.png|right|frame|'''Figure 1.''' The Lights Page.]] The '''Lights Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] 4aaa635e204f5fe9f84c1aa7026889fefb98da46 Markers Page 0 458 461 2023-07-15T12:21:46Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_markers.png|right|frame|'''Figure 1.''' The Markers Page.]] The '''Markers Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_markers.png|right|frame|'''Figure 1.''' The Markers Page.]] The '''Markers Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] f4165a8e771230672ff2f30b7ef15ecde47c9b88 Material Page 0 459 462 2023-07-15T12:22:14Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_material.png|right|frame|'''Figure 1.''' The Material Page.]] The '''Material Page''' is a tool page in the [[World Editor]]. It can be found under the '''Material''' tab. A material can be embedded inside a world or referenced as an external resource. (Material resources have the <code>.mtl</code> extension.) Both types are displayed in the same list inside the Material Page. The names of materials embedded inside a world, if they are named at a..." wikitext text/x-wiki __NOTOC__ [[File:Editor_material.png|right|frame|'''Figure 1.''' The Material Page.]] The '''Material Page''' is a tool page in the [[World Editor]]. It can be found under the '''Material''' tab. A material can be embedded inside a world or referenced as an external resource. (Material resources have the <code>.mtl</code> extension.) Both types are displayed in the same list inside the Material Page. The names of materials embedded inside a world, if they are named at all, are displayed in plain type, and the names of materials stored in external resources are displayed in bold type. A material can be edited in the [[Material Editor]] by double-clicking on it or selecting it and choosing '''Edit Material''' from the popup menu in the Material Page. When a material stored in an external resource is edited, the modified material is saved back to the resource, which affects any world using the same resource. Edits made to a material embedded in a world are local to that world. == Managing Materials == The popup menu in the upper-right corner of the page contains the commands used to manage materials. Each command is described in the following table. {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|'''Edit&nbsp;Material...'''|Opens the [[Material Editor]] to edit the selected material.}} |- {{Tablerow|'''Select&nbsp;All&nbsp;with&nbsp;Material'''|Selects all nodes in the world that use the selected material.}} |- {{Tablerow|'''New&nbsp;Material'''|Creates a new empty material.}} |- {{Tablerow|'''Copy&nbsp;Material'''|Copies the selected material to the clipboard.}} |- {{Tablerow|'''Paste&nbsp;Material'''|Pastes a material from the clipboard.}} |- {{Tablerow|'''Duplicate&nbsp;Material'''|Duplicates the selected material.}} |- {{Tablerow|'''Delete&nbsp;Material'''|Deletes the selected material. This is available only if the material is not being used by any nodes in the world. (If the material is stored in a resource, this does not delete the resource. It only removes the material from the list in the Material Page.)}} |- {{Tablerow|'''Add&nbsp;Materials...'''|Adds materials stored in resources to the list available for use in the world.}} |- {{Tablerow|'''Replace&nbsp;Material...'''|Replaces the selected material with another material stored in a resource.}} |- {{Tablerow|'''Import&nbsp;Material'''|If the selected material is stored in a resource, imports it into the world as an embedded material.}} |- {{Tablerow|'''Export&nbsp;Material...'''|Saves the selected material as an external resource and changes the entry in the Material Page to a reference to that resource.}} |- {{Tablerow|'''Cleanup&nbsp;Material&nbsp;List'''|Adds any materials used in the world to the list shown in the Material Page and consolidates any duplicate materials.}} |} == Material Pickup == The '''Material Pickup''' tool in the upper-left corner of the Material Page can be used to select the material used in a world. When this tool is selected, you can click on any surface in an editor viewport, and if that surface belongs to a node that is not part of an external instance, then the material used by the surface is selected in the Material Page. == See Also == * [[Material Editor]] * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] 3bd7bbc97819fd23019dbf545364736873c1fbf1 Models Page 0 460 463 2023-07-15T12:23:02Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_models.png|right|frame|'''Figure 1.''' The Models Page.]] The '''Models Page''' is a tool page in the [[World Editor]]. It can be found under the '''Instance''' tab. The list shown in the Models Page displays all of the models registered with the engine. When a model in the list is selected, clicking in an editor viewport places a new instance of that model in the world and attaches the default controller to it. (The type of the default controlle..." wikitext text/x-wiki __NOTOC__ [[File:Editor_models.png|right|frame|'''Figure 1.''' The Models Page.]] The '''Models Page''' is a tool page in the [[World Editor]]. It can be found under the '''Instance''' tab. The list shown in the Models Page displays all of the models registered with the engine. When a model in the list is selected, clicking in an editor viewport places a new instance of that model in the world and attaches the default controller to it. (The type of the default controller for a particular model is specified by the model's registration.) Placement adjustments are applied if they're enabled in the [[Placement Page]]. The '''Generic Model''' tool in the upper-left corner of the Models Page places a generic model in the world. A model resource can be assigned to a generic model under the '''Model''' tab in the Node Info window. An [[Animation Controller]] is typically attached to a generic model under the '''Controller''' tab in the Node Info window. == Managing Models == The popup menu in the upper-right corner of the page contains the commands used to manage models. Each command is described in the following table. {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|'''Select&nbsp;All'''|Selects all of the models in the world having the selected type.}} |- {{Tablerow|'''Select&nbsp;Some...'''|Randomly selects a portion of the models in the world having the selected type. A dialog box is displayed to let you specify a percentage.}} |- {{Tablerow|'''Expand&nbsp;All&nbsp;in&nbsp;Scene&nbsp;Graph'''|Expands the subnode tree in the scene graph viewport for all models in the world having the selected type.}} |- {{Tablerow|'''Collapse&nbsp;All&nbsp;in&nbsp;Scene&nbsp;Graph'''|Collapses the subnode tree in the scene graph viewport for all models in the world having the selected type.}} |} == See Also == * [[World Editor Pages]] * [[World Editor]] * [[Model Viewer]] * [[Animation Controller]] [[Category:Editor]] 341634224855f6b0d9170e8cb9f7d2f5842afd93 Node Management Page 0 461 464 2023-07-15T12:23:29Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_nodemanagement.png|right|frame|'''Figure 1.''' The Node Management Page.]] The '''Node Management Page''' is a tool page in the [[World Editor]]. It can be found under the '''Editor''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_nodemanagement.png|right|frame|'''Figure 1.''' The Node Management Page.]] The '''Node Management Page''' is a tool page in the [[World Editor]]. It can be found under the '''Editor''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] 92945774eaaa886da7c574161a5ac1d02060625b Paint Page 0 462 465 2023-07-15T12:23:52Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_paint.png|right|frame|'''Figure 1.''' The Paint Page.]] The '''Paint Page''' is a tool page in the [[World Editor]]. It can be found under the '''Material''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_paint.png|right|frame|'''Figure 1.''' The Paint Page.]] The '''Paint Page''' is a tool page in the [[World Editor]]. It can be found under the '''Material''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] a88bcfb7595e5ba4ffbf9dacc8deb890f325d29d Particles Page 0 463 466 2023-07-15T12:24:11Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_particles.png|right|frame|'''Figure 1.''' The Particles Page.]] The '''Particles Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_particles.png|right|frame|'''Figure 1.''' The Particles Page.]] The '''Particles Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] 7597ed27945c29e033e79e3514759658e9fa750a Paths Page 0 464 467 2023-07-15T12:24:32Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_paths.png|right|frame|'''Figure 1.''' The Paths Page.]] The '''Paths Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_paths.png|right|frame|'''Figure 1.''' The Paths Page.]] The '''Paths Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] 31210a35f4a0d12db3fbef9135e68de5fd8c3e49 Physics Page 0 465 468 2023-07-15T12:25:00Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_physics.png|right|frame|'''Figure 1.''' The Physics Page.]] The '''Physics Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] * [[Physics]] [[Category:Editor]] [[Category:Physics]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_physics.png|right|frame|'''Figure 1.''' The Physics Page.]] The '''Physics Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] * [[Physics]] [[Category:Editor]] [[Category:Physics]] 55c7daca725308f9866a9edf29627c74cfb1f1cb Placement Page 0 466 469 2023-07-15T12:25:38Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_placement.png|right|frame|'''Figure 1.''' The Placement Page.]] The '''Placement Page''' is a tool page in the [[World Editor]]. It can be found under the '''Instance''' tab, and it contains settings that control how the transforms of instances, models, and markers are adjusted when they are placed in the world. Placement adjustments are applied only when the '''Enable adjustments''' box is checked at the time when a new instance, model, or marke..." wikitext text/x-wiki __NOTOC__ [[File:Editor_placement.png|right|frame|'''Figure 1.''' The Placement Page.]] The '''Placement Page''' is a tool page in the [[World Editor]]. It can be found under the '''Instance''' tab, and it contains settings that control how the transforms of instances, models, and markers are adjusted when they are placed in the world. Placement adjustments are applied only when the '''Enable adjustments''' box is checked at the time when a new instance, model, or marker is created. The current placement settings can be applied to all currently selected instances, models, and markers by clicking on the '''Apply to Selection''' button. The placement settings have the following meanings. {| {{Table}} {{Tablehead|Setting|Description}} |- {{Tablerow|'''Randomize&nbsp;rotation'''|If checked, the new node is rotated about the vertical axis by a random angle. Enabling this setting ensures that objects like trees don't all have the same orientation.}} |- {{Tablerow|'''Align&nbsp;to&nbsp;tan&nbsp;plane'''|If checked, the new node is aligned with the tangent plane of the ground. This is useful for placing objects on sloped surfaces.}} |- {{Tablerow|'''Sink&nbsp;into&nbsp;ground'''|If checked, the new node is moved downward so that a disk at the base of the node is completely underground. The radius of the disk is specified by the '''Sink radius''' setting. Enabling this setting ensures that objects like trees are sunk into the ground far enough that no part of the base sticks out of a sloped surface.}} |- {{Tablerow|'''Sink&nbsp;radius'''|This specifies the radius of the disk that is used to test whether the base of a node is underground when the '''Sink into ground''' box is checked.}} |- {{Tablerow|'''Apply&nbsp;random&nbsp;tilt'''|If checked, the new node is tilted about a randomly chosen horizontal axis according to the tilt settings that follow.}} |- {{Tablerow|'''Tilt&nbsp;probability'''|If the '''Apply random tilt''' box is checked, this determines how probable it is that any tilt will be applied.}} |- {{Tablerow|'''Min&nbsp;tilt&nbsp;angle&nbsp;(deg)'''|This specifies the minimum angle, in degrees, by which a new node is randomly tilted when the '''Apply random tilt''' box is checked.}} |- {{Tablerow|'''Max&nbsp;tilt&nbsp;angle&nbsp;(deg)'''|This specifies the maximum angle, in degrees, by which a new node is randomly tilted when the '''Apply random tilt''' box is checked.}} |- {{Tablerow|'''Apply&nbsp;random&nbsp;offset'''|If checked, the new node is offset in the vertical direction according to the offset settings that follow.}} |- {{Tablerow|'''Offset&nbsp;probability'''|If the '''Apply random offset''' box is checked, this determines how probable it is that any offset will be applied.}} |- {{Tablerow|'''Min&nbsp;Z&nbsp;offset'''|This specifies the minimum distance by which a new node is randomly offset when the '''Apply random offset''' box is checked. Positive values are up, and negative values are down.}} |- {{Tablerow|'''Max&nbsp;Z&nbsp;offset'''|This specifies the maximum distance by which a new node is randomly offset when the '''Apply random offset''' box is checked. Positive values are up, and negative values are down.}} |} == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] f2838a89c5eb9a01bc6e2c0ae987cf45e30b8ecf Portals Page 0 467 470 2023-07-15T12:26:03Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_portals.png|right|frame|'''Figure 1.''' The Portals Page.]] The '''Portals Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_portals.png|right|frame|'''Figure 1.''' The Portals Page.]] The '''Portals Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] e4d839bf0ea66d1f3aa451f7799a5120e35baa6b Sources Page 0 468 471 2023-07-15T12:26:26Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_sources.png|right|frame|'''Figure 1.''' The Sources Page.]] The '''Sources Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_sources.png|right|frame|'''Figure 1.''' The Sources Page.]] The '''Sources Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] 198f256238f36b4a38bdd88a1a971639083b4b2d Terrain 0 469 472 2023-07-15T12:26:51Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_terrain.png|right|frame|'''Figure 1.''' The Terrain Page.]] The '''Terrain Page''' is a tool page in the [[World Editor]]. It can be found under the '''Earth''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] * [[Terrain Palettes]] * [[Terrain Tutorial]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_terrain.png|right|frame|'''Figure 1.''' The Terrain Page.]] The '''Terrain Page''' is a tool page in the [[World Editor]]. It can be found under the '''Earth''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] * [[Terrain Palettes]] * [[Terrain Tutorial]] [[Category:Editor]] 61a0c0f9b86f1534d1d03e3b033672fb104416e3 Terrain Palettes 0 470 473 2023-07-15T12:27:41Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:terrainpalette.png|right|frame|'''Figure 1.''' The Terrain Palette dialog.]] A '''terrain palette''' is a set of textures that can be used to paint voxel-based terrain geometry. A terrain palette texture resource is a special kind of <code>.tex</code> file that contains references to several other texture maps. The terrain palette is a very small file because the texture image data remains in the referenced resources. A different terrain palette would ty..." wikitext text/x-wiki __NOTOC__ [[File:terrainpalette.png|right|frame|'''Figure 1.''' The Terrain Palette dialog.]] A '''terrain palette''' is a set of textures that can be used to paint voxel-based terrain geometry. A terrain palette texture resource is a special kind of <code>.tex</code> file that contains references to several other texture maps. The terrain palette is a very small file because the texture image data remains in the referenced resources. A different terrain palette would typically be created for each world, or possibly for each terrain block in a large world containing multiple terrain blocks. The entries in a terrain palette are just ordinary 2D texture maps that have already been imported using the [[Texture Importer]]. == Creating a Terrain Palette Texture Resource == A terrain palette is created by selecting the '''Generate Terrain Palette''' command from the [[C4 Menu]] or by entering <code>texpal</code> in the [[Command Console]]. The Terrain Palette dialog (shown in Figure 1) then appears with an empty list of input texture maps. Texture maps are added to the palette by clicking the '''Add''' button and choosing the textures that you want to be part of the palette. Multiple texture maps can be added at once by holding the Shift key to choose multiple files from the file selection dialog that appears after you click the '''Add''' button. Once you have added all of the texture maps that will be part of the terrain palette, click the '''Save''' button. You will then be asked to name the output texture resource containing your new palette. == Input Texture Map Requirements == The texture maps to be included in a terrain palette must satisfy the following requirements: * All textures in the palette have the same dimensions. * The width and height of the palette entries are at least 32 pixels. * The texture size is square (i.e., the width and height are the same). * All textures use block compression (shown as BC1/3 in the list of input textures). * All textures have the same alpha channel usage. This information is shown for each entry in the list of input textures so that it's easy to spot problems. <br clear="both" /> == Command Line == The <code>texpal</code> command can also be used as a standalone command line tool. (The dialog appears when no parameters are specified.) The command has the following usage: texpal -o <''output-name''> <''input-name-1''> <''input-name-2''> ... The ''output-name'' is the name of the output terrain palette file (without extension) relative to the <code>Data</code> directory. This name does include the top-level directory name in its path. Each of the ''input-name'' identifiers must name an existing texture map resource using the standard resource naming conventions, meaning that the top-level directory name under the <code>Data</code> folder is ''not'' included in the path. Any number of input texture maps can be specified, but the number of entries should be kept as small as possible for best performance. == See Also == * [[Texture Importer]] * [[Terrain]] 8c15cd3e700f6352b1c9a8d4b9b364c009bdf9a8 Texture Mapping Page 0 471 474 2023-07-15T12:28:08Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_texturemapping.png|right|frame|'''Figure 1.''' The Texture Mapping Page.]] The '''Texture Mapping Page''' is a tool page in the [[World Editor]]. It can be found under the '''Material''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_texturemapping.png|right|frame|'''Figure 1.''' The Texture Mapping Page.]] The '''Texture Mapping Page''' is a tool page in the [[World Editor]]. It can be found under the '''Material''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] e6c86f75bff621bc7ad5b57c0afc58c9c1772856 Transform Page 0 472 475 2023-07-15T12:28:44Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_transform.png|right|frame|'''Figure 1.''' The Transform Page.]] The '''Transform Page''' is a tool page in the [[World Editor]]. It can be found under the '''Editor''' tab. The position and rotation values are specified in the object space of the selected node. The '''Copy''' button copies the current position, rotation, or both, depending on which radio button is selected underneath. The '''Paste''' button applies a previously copied transform..." wikitext text/x-wiki __NOTOC__ [[File:Editor_transform.png|right|frame|'''Figure 1.''' The Transform Page.]] The '''Transform Page''' is a tool page in the [[World Editor]]. It can be found under the '''Editor''' tab. The position and rotation values are specified in the object space of the selected node. The '''Copy''' button copies the current position, rotation, or both, depending on which radio button is selected underneath. The '''Paste''' button applies a previously copied transform to the currently selected node. The '''Reset''' button resets the transform for the selected node to the identity matrix. The radio buttons for position, rotation, or both also apply to the '''Reset''' button so that it's possible to reset only the position or rotation without affecting the other. The values under '''Size''' specify the dimensions of the selected node. The '''X''', '''Y''', and '''Z''' dimensions always refer to lengths along the object-space ''x'', ''y'', and ''z'' axes. The '''A''', '''B''', and '''C''' dimensions are used for additional lengths for some types of objects. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] b9c28929130e12497392b85b0dfcb49af386b5cf Triggers 0 473 476 2023-07-15T12:29:23Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_triggers.png|right|frame|'''Figure 1.''' The Triggers Page.]] The '''Triggers Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. A trigger node is used to detect when some object has entered or exited a specific volume of space. The engine defines three different shapes for a trigger volume: a box, a cylinder, and a sphere. The trigger nodes in a world are activated and deactivated by calling the [http://c..." wikitext text/x-wiki __NOTOC__ [[File:Editor_triggers.png|right|frame|'''Figure 1.''' The Triggers Page.]] The '''Triggers Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. A trigger node is used to detect when some object has entered or exited a specific volume of space. The engine defines three different shapes for a trigger volume: a box, a cylinder, and a sphere. The trigger nodes in a world are activated and deactivated by calling the [http://c4engine.com/docs/WorldMgr/World_ActivateTriggers.html World::ActivateTriggers()] function. The old and new positions of an object are typically passed to this function to determine whether the line segment connecting them has intersected any trigger volumes. When a trigger is activated, the engine takes the following steps. * If the trigger node itself has a controller, then that controller is activated. * If the trigger object specifies an activation connector key and there is a node connected to the trigger through a connector having that key, then: ** If that node has a controller, then that controller is activated. ** Otherwise, the immediate subnodes of that node are examined, and ''every'' controller belonging to that set of subnodes is activated. If the activated controller is a script controller that is configured to handle controller activation events (which is the default), then the script is executed. On the first frame after a trigger node is activated, if it no longer intersects any line segments passed to the [http://c4engine.com/docs/WorldMgr/World_ActivateTriggers.html World::ActivateTriggers()] function, then it becomes deactivated. When a trigger node is deactivated, it takes the following steps, similar to the activation process. * If the trigger node itself has a controller, then that controller is deactivated. * If the trigger object specifies a deactivation connector key and there is a node connected to the trigger through a connector having that key, then: ** If that node has a controller, then that controller is deactivated. ** Otherwise, the immediate subnodes of that node are examined, and ''every'' controller belonging to that set of subnodes is deactivated. If the deactivated controller is a script controller that is configured to handle controller deactivation events, then the script is executed. A script does not handle deactivation events by default, so it has to be configured as such by double-clicking on the script name in the [[Script Editor]] and checking the '''Handles controller deactivate event''' box. A single script can handle both activate and deactivate events if both boxes are checked in the script settings. In this case, different paths of execution can be followed by using the '''Controller Activate Event''' and '''Controller Deactivate Event''' methods to determine which type of event actually caused the script to run. == Trigger Settings == A trigger node can be configured under the Trigger tab in the Node Info window. The specific settings are described in the following table. {| {{Table}} {{Tablehead|Setting|Description}} |- {{Tablerow|'''Disabled&nbsp;after&nbsp;activation'''|The trigger node is disabled immediately after the first time it is activated so that it is activated only once. (It's possible to explicitly re-enable the trigger later.)}} |- {{Tablerow|'''Continuously&nbsp;activated'''|The trigger is activated for each frame during which an object is inside it instead of waiting for the object to leave and re-enter.}} |- {{Tablerow|'''Activation&nbsp;connector&nbsp;key'''|An optional connector key specifying a link to the node that receives the activation event when the trigger is activated. This is used only if the trigger node itself does not have a controller.}} |- {{Tablerow|'''Deactivation&nbsp;connector&nbsp;key'''|An optional connector key specifying a link to the node that receives the deactivation event when the trigger is deactivated. This is used only if the trigger node itself does not have a controller.}} |} == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] da25565c4eaa97d1368b58584cbf32f4dad1b810 Viewports Page 0 474 477 2023-07-15T12:29:52Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_viewports.png|right|frame|'''Figure 1.''' The Viewports Page.]] The '''Viewports Page''' is a tool page in the [[World Editor]]. It can be found under the '''Editor''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_viewports.png|right|frame|'''Figure 1.''' The Viewports Page.]] The '''Viewports Page''' is a tool page in the [[World Editor]]. It can be found under the '''Editor''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] 3e9a80fc28a38eb15d3b3387ba577c3e5db3e0c9 Water Page 0 475 478 2023-07-15T12:30:12Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_water.png|right|frame|'''Figure 1.''' The Water Page.]] The '''Water Page''' is a tool page in the [[World Editor]]. It can be found under the '''Earth''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_water.png|right|frame|'''Figure 1.''' The Water Page.]] The '''Water Page''' is a tool page in the [[World Editor]]. It can be found under the '''Earth''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] c6fb87a1d341c1ae27cbfc0d5a9c3ca37c817828 Worlds Page 0 476 479 2023-07-15T12:30:37Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_worlds.png|right|frame|'''Figure 1.''' The Worlds Page.]] The '''Worlds Page''' is a tool page in the [[World Editor]]. It can be found under the '''Instance''' tab. The list shown in the Worlds Page displays the instanced world resources that have been placed in the current world. When a world in the list is selected, clicking in an editor viewport places a new instance of that world in the current world. Placement adjustments are applied if the..." wikitext text/x-wiki __NOTOC__ [[File:Editor_worlds.png|right|frame|'''Figure 1.''' The Worlds Page.]] The '''Worlds Page''' is a tool page in the [[World Editor]]. It can be found under the '''Instance''' tab. The list shown in the Worlds Page displays the instanced world resources that have been placed in the current world. When a world in the list is selected, clicking in an editor viewport places a new instance of that world in the current world. Placement adjustments are applied if they're enabled in the [[Placement Page]]. If multiple worlds are selected (by using shift-click or control-click), then one is chosen at random each time you click in a viewport. The '''Instanced World''' tool in the upper-left corner of the Worlds Page places a blank instance in the world. A world resource can be assigned to it under the '''World''' tab in the Node Info window. If the '''Place on instances''' box is checked, then new instances can be placed on surfaces belonging to other instances already in the world. If this is not checked, then other instances are ignored, and new instances are placed only on surfaces that are part of the main world. == Modifiers == Instanced worlds may have one or more ''modifiers'' attach to them. A modifier changes the instanced world in some way at the time it's loaded. After an instance has been placed in the world, modifiers can be added and edited under the '''Modifiers''' tab in the Node Info window. See [[Modifiers]] for information about the specific modifiers that are available. The Worlds Page contains a list of modifier presets that can be used to automatically applied frequently used modifiers to instances as they're placed in a world. A modifier preset is created by selecting an existing instance in the world that already has modifiers attached to it and choosing '''New Modifier Preset''' from the popup menu in the Worlds Page. When a modifier preset is selected in the Worlds Page, its modifiers are copied to each new instance that is placed in a world. == Managing Worlds == The popup menu in the upper-right corner of the page contains the commands used to manage instanced worlds. Each command is described in the following table. {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|'''Select&nbsp;All'''|Selects all of the instances in the world referencing the selected resource(s).}} |- {{Tablerow|'''Select&nbsp;Some...'''|Randomly selects a portion of the instances in the world referencing the selected resource(s). A dialog box is displayed to let you specify a percentage.}} |- {{Tablerow|'''Expand&nbsp;All&nbsp;in&nbsp;Scene&nbsp;Graph'''|Expands the subnode tree in the scene graph viewport for all instances in the world referencing the selected resource(s).}} |- {{Tablerow|'''Collapse&nbsp;All&nbsp;in&nbsp;Scene&nbsp;Graph'''|Collapses the subnode tree in the scene graph viewport for all instances in the world referencing the selected resource(s).}} |- {{Tablerow|'''Replace&nbsp;Instances'''|Replaces all of the instances selected in the current world with the instance selected in the Worlds Page. (This is available only when exactly one world is selected in the Worlds Page.)}} |- {{Tablerow|'''Replace&nbsp;Modifiers'''|For each instance selected in the current world, replaces the modifiers with those corresponding to the selected modifier preset.}} |- {{Tablerow|'''New&nbsp;Modifier&nbsp;Preset...'''|Creates a new modifier preset based on the currently selected instance. A dialog is displayed to let you give the preset a name. (This is available only when exactly one instance is selected in the world.)}} |- {{Tablerow|'''Delete&nbsp;Modifier&nbsp;Preset'''|Deletes the selected modifier preset.}} |- {{Tablerow|'''Rename&nbsp;Modifier&nbsp;Preset'''|Displays a dialog to let you rename the selected modifier preset.}} |- {{Tablerow|'''Cleanup&nbsp;Instance&nbsp;List'''|Adds the names of all instances used by the current world to the instance list and removes any instances that are not used.}} |} == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] d41924d87eca970f27cd29b5527634167dc6a681 Zones Page 0 477 480 2023-07-15T12:30:53Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Editor_zones.png|right|frame|'''Figure 1.''' The Zones Page.]] The '''Zones Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]]" wikitext text/x-wiki __NOTOC__ [[File:Editor_zones.png|right|frame|'''Figure 1.''' The Zones Page.]] The '''Zones Page''' is a tool page in the [[World Editor]]. It can be found under the '''Object''' tab. == See Also == * [[World Editor Pages]] * [[World Editor]] [[Category:Editor]] 1609324a4c9928e5449b05258cb0ff54a0d3b9fc Widgets 0 478 481 2023-07-15T12:31:44Z Eric Lengyel 1 Created page with "A '''widget''' is an individual component of a window, panel, or any kind of interface displayed to the user. There are many different types of widgets defined by the C4 Engine, and these are described in the table below. Applications can also define their own custom widget types. Click on the name of a widget for information about the specific settings for that type of widget. {| style="border: solid 1px #444; border-spacing: 0px; border-collapse: collapse;" {{Tableh..." wikitext text/x-wiki A '''widget''' is an individual component of a window, panel, or any kind of interface displayed to the user. There are many different types of widgets defined by the C4 Engine, and these are described in the table below. Applications can also define their own custom widget types. Click on the name of a widget for information about the specific settings for that type of widget. {| style="border: solid 1px #444; border-spacing: 0px; border-collapse: collapse;" {{Tablehead|Widget|Description}} |- {{Tableimage|[[Image:widget_border.png]]|[[Border Widget|'''Border''']]. This widget displays a one-pixel-wide rectangular border.}} |- {{Tableimage|[[Image:widget_camera.png]]|[[Camera Widget|'''Camera''']]. This widget displays a remote camera view in the world being played. (Only available for in-game panel effects.)}} |- {{Tableimage|[[Image:widget_check.png]]|[[Check Widget|'''Check Box''']]. This widget displays a check box that can be in the checked state or unchecked state.}} |- {{Tableimage|[[Image:widget_color.png]]|[[Color Widget|'''Color Box''']]. This widget displays a color selection box that displays a color picker dialog when clicked.}} |- {{Tableimage|[[Image:widget_config.png]]|[[Configuration Widget|'''Configuration Table''']]. This widget displays a configuration table that is used to show property settings to the user.}} |- {{Tableimage|[[Image:widget_edittext.png]]|[[Edit Text Widget|'''Editable Text Box''']]. This widget displays an editable text box that allows a single line or multiple lines of text entry.}} |- {{Tableimage|[[Image:widget_viewport.png]]|[[Frustum Viewport Widget|'''Frustum Viewport''']]. This widget displays a viewport with a frustum camera.}} |- {{Tableimage|[[Image:widget_hyperlink.png]]|[[Hyperlink Widget|'''Hyperlink''']]. This widget displays a text button with a hyperlink.}} |- {{Tableimage|[[Image:widget_icon.png]]|[[Icon Widget|'''Icon''']]. This widget displays a vector icon.}} |- {{Tableimage|[[Image:widget_iconbutton.png]]|[[Icon Button Widget|'''Icon Button''']]. This widget displays a button with a vector icon.}} |- {{Tableimage|[[Image:widget_image.png]]|[[Image Widget|'''Image''']]. This widget displays a plain texture image.}} |- {{Tableimage|[[Image:widget_imagebutton.png]]|[[Image Button Widget|'''Image Button''']]. This widget displays a button with a texture image.}} |- {{Tableimage|[[Image:widget_line.png]]|[[Line Widget|'''Line''']]. This widget displays a one-pixel-wide line that can be solid, dotted, or dashed.}} |- {{Tableimage|[[Image:widget_list.png]]|[[List Widget|'''List''']]. This widget displays a list box with a scroll bar.}} |- {{Tableimage|[[Image:widget_menubar.png]]|[[Menu Bar Widget|'''Menu Bar''']]. This widget displays a menu bar that allows the user to choose commands from pull-down menus.}} |- {{Tableimage|[[Image:widget_movie.png]]|[[Movie Widget|'''Movie''']]. This widget plays a movie resource.}} |- {{Tableimage|[[Image:widget_multipane.png]]|[[Multipane Widget|'''Multipane Box''']]. This widget displays a multipane box.}} |- {{Tableimage|[[Image:widget_picture.png]]|[[Picture Widget|'''Picture''']]. This widget displays a vector picture.}} |- {{Tableimage|[[Image:widget_viewport.png]]|[[Ortho Viewport Widget|'''Ortho Viewport''']]. This widget displays a viewport with an orthographic camera.}} |- {{Tableimage|[[Image:widget_paint.png]]|[[Paint Widget|'''Paint''']]. This widget displays an interactive painting canvas.}} |- {{Tableimage|[[Image:widget_password.png]]|[[Password Widget|'''Password''']]. This widget displays a password entry box that obscures the text entered into it.}} |- {{Tableimage|[[Image:widget_popupmenu.png]]|[[Popup Menu Widget|'''Popup Menu''']]. This widget displays a popup menu.}} |- {{Tableimage|[[Image:widget_progress.png]]|[[Progress Widget|'''Progress Bar''']]. This widget displays a progress bar.}} |- {{Tableimage|[[Image:widget_pushbutton.png]]|[[Push Button Widget|'''Push Button''']]. This widget displays a button with a text string.}} |- {{Tableimage|[[Image:widget_quad.png]]|[[Quad Widget|'''Quad''']]. This widget displays a plain colored quad.}} |- {{Tableimage|[[Image:widget_radio.png]]|[[Radio Widget|'''Radio Button''']]. This widget displays a radio button that can be in the selected or unselected state.}} |- {{Tableimage|[[Image:widget_scroll.png]]|[[Scroll Widget|'''Scroll Bar''']]. This widget displays a scroll bar.}} |- {{Tableimage|[[Image:widget_slider.png]]|[[Slider Widget|'''Slider''']]. This widget displays a slider.}} |- {{Tableimage|[[Image:widget_stroke.png]]|[[Stroke Widget|'''Stroke''']]. This widget displays a vector line with optional cap styles and dashing.}} |- {{Tableimage|[[Image:widget_list.png]]|[[Table Widget|'''Table''']]. This widget displays a table with a fixed number of columns in a box with a scroll bar.}} |- {{Tableimage|[[Image:widget_text.png]]|[[Text Widget|'''Text''']]. This widget displays a plain text string.}} |- {{Tableimage|[[Image:widget_textbutton.png]]|[[Text Button Widget|'''Text Button''']]. This widget displays a clickable text string.}} |- {{Tableimage|[[Image:widget_list.png]]|[[Tree Widget|'''Tree''']]. This widget displays a list box with a scroll bar, and the items can have collapsable subtrees.}} |- {{Tableimage|[[Image:widget_viewport.png]]|[[World Viewport Widget|'''World Viewport''']]. This widget renders a complete world inside a frustum viewport, and the it provides camera orbit functionality.}} |} == See Also == * [[Panel Editor]] * [[Sprockets]] * [[Functions]] * [http://c4engine.com/docs/InterfaceMgr/Widget_tree.html Widget class hierarchy] [[Category:Interface]] e4f224b30bcf39a3ad013a607592fc8ad917d6ba 494 481 2023-07-15T12:40:30Z Eric Lengyel 1 wikitext text/x-wiki A '''widget''' is an individual component of a window, panel, or any kind of interface displayed to the user. There are many different types of widgets defined by the C4 Engine, and these are described in the table below. Applications can also define their own custom widget types. Click on the name of a widget for information about the specific settings for that type of widget. {| style="border: solid 1px #444; border-spacing: 0px; border-collapse: collapse;" {{Tablehead|Widget|Description}} |- {{Tableimage|[[Image:widget_border.png]]|[[Border Widget|'''Border''']]. This widget displays a one-pixel-wide rectangular border.}} |- {{Tableimage|[[Image:widget_camera.png]]|[[Camera Widget|'''Camera''']]. This widget displays a remote camera view in the world being played. (Only available for in-game panel effects.)}} |- {{Tableimage|[[Image:widget_check.png]]|[[Check Widget|'''Check Box''']]. This widget displays a check box that can be in the checked state or unchecked state.}} |- {{Tableimage|[[Image:widget_color.png]]|[[Color Widget|'''Color Box''']]. This widget displays a color selection box that displays a color picker dialog when clicked.}} |- {{Tableimage|[[Image:widget_config.png]]|[[Configuration Widget|'''Configuration Table''']]. This widget displays a configuration table that is used to show property settings to the user.}} |- {{Tableimage|[[Image:widget_edittext.png]]|[[Edit Text Widget|'''Editable Text Box''']]. This widget displays an editable text box that allows a single line or multiple lines of text entry.}} |- {{Tableimage|[[Image:widget_viewport.png]]|[[Frustum Viewport Widget|'''Frustum Viewport''']]. This widget displays a viewport with a frustum camera.}} |- {{Tableimage|[[Image:widget_hyperlink.png]]|[[Hyperlink Widget|'''Hyperlink''']]. This widget displays a text button with a hyperlink.}} |- {{Tableimage|[[Image:widget_icon.png]]|[[Icon Widget|'''Icon''']]. This widget displays a vector icon.}} |- {{Tableimage|[[Image:widget_iconbutton.png]]|[[Icon Button Widget|'''Icon Button''']]. This widget displays a button with a vector icon.}} |- {{Tableimage|[[Image:widget_image.png]]|[[Image Widget|'''Image''']]. This widget displays a plain texture image.}} |- {{Tableimage|[[Image:widget_imagebutton.png]]|[[Image Button Widget|'''Image Button''']]. This widget displays a button with a texture image.}} |- {{Tableimage|[[Image:widget_line.png]]|[[Line Widget|'''Line''']]. This widget displays a one-pixel-wide line that can be solid, dotted, or dashed.}} |- {{Tableimage|[[Image:widget_list.png]]|[[List Widget|'''List''']]. This widget displays a list box with a scroll bar.}} |- {{Tableimage|[[Image:widget_menubar.png]]|[[Menu Bar Widget|'''Menu Bar''']]. This widget displays a menu bar that allows the user to choose commands from pull-down menus.}} |- {{Tableimage|[[Image:widget_movie.png]]|[[Movie Widget|'''Movie''']]. This widget plays a movie resource.}} |- {{Tableimage|[[Image:widget_multipane.png]]|[[Multipane Widget|'''Multipane Box''']]. This widget displays a multipane box.}} |- {{Tableimage|[[Image:widget_viewport.png]]|[[Ortho Viewport Widget|'''Ortho Viewport''']]. This widget displays a viewport with an orthographic camera.}} |- {{Tableimage|[[Image:widget_paint.png]]|[[Paint Widget|'''Paint''']]. This widget displays an interactive painting canvas.}} |- {{Tableimage|[[Image:widget_password.png]]|[[Password Widget|'''Password''']]. This widget displays a password entry box that obscures the text entered into it.}} |- {{Tableimage|[[Image:widget_picture.png]]|[[Picture Widget|'''Picture''']]. This widget displays a vector picture.}} |- {{Tableimage|[[Image:widget_popupmenu.png]]|[[Popup Menu Widget|'''Popup Menu''']]. This widget displays a popup menu.}} |- {{Tableimage|[[Image:widget_progress.png]]|[[Progress Widget|'''Progress Bar''']]. This widget displays a progress bar.}} |- {{Tableimage|[[Image:widget_pushbutton.png]]|[[Push Button Widget|'''Push Button''']]. This widget displays a button with a text string.}} |- {{Tableimage|[[Image:widget_quad.png]]|[[Quad Widget|'''Quad''']]. This widget displays a plain colored quad.}} |- {{Tableimage|[[Image:widget_radio.png]]|[[Radio Widget|'''Radio Button''']]. This widget displays a radio button that can be in the selected or unselected state.}} |- {{Tableimage|[[Image:widget_scroll.png]]|[[Scroll Widget|'''Scroll Bar''']]. This widget displays a scroll bar.}} |- {{Tableimage|[[Image:widget_slider.png]]|[[Slider Widget|'''Slider''']]. This widget displays a slider.}} |- {{Tableimage|[[Image:widget_stroke.png]]|[[Stroke Widget|'''Stroke''']]. This widget displays a vector line with optional cap styles and dashing.}} |- {{Tableimage|[[Image:widget_list.png]]|[[Table Widget|'''Table''']]. This widget displays a table with a fixed number of columns in a box with a scroll bar.}} |- {{Tableimage|[[Image:widget_text.png]]|[[Text Widget|'''Text''']]. This widget displays a plain text string.}} |- {{Tableimage|[[Image:widget_textbutton.png]]|[[Text Button Widget|'''Text Button''']]. This widget displays a clickable text string.}} |- {{Tableimage|[[Image:widget_list.png]]|[[Tree Widget|'''Tree''']]. This widget displays a list box with a scroll bar, and the items can have collapsable subtrees.}} |- {{Tableimage|[[Image:widget_viewport.png]]|[[World Viewport Widget|'''World Viewport''']]. This widget renders a complete world inside a frustum viewport, and the it provides camera orbit functionality.}} |} == See Also == * [[Panel Editor]] * [[Sprockets]] * [[Functions]] * [http://c4engine.com/docs/InterfaceMgr/Widget_tree.html Widget class hierarchy] [[Category:Interface]] 8533c181bd925dee14b2db8e5d24f6a34004c053 Template:Tableimage 10 479 482 2023-07-15T12:32:07Z Eric Lengyel 1 Created page with "| style="vertical-align: middle; text-align: center; background-color: white; border: solid 1px #444; padding: 2px 24px 2px 6px;" | {{{1}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{2}}}" wikitext text/x-wiki | style="vertical-align: middle; text-align: center; background-color: white; border: solid 1px #444; padding: 2px 24px 2px 6px;" | {{{1}}} | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | {{{2}}} 48724fc0a9090cdd31d59e88d9775260df91fc3c Border Widget 0 480 483 2023-07-15T12:33:25Z Eric Lengyel 1 Created page with "The '''Border Widget''' displays a one-pixel-wide rectangular border. The border is rendered around the outside of the actual boundary of the widget so that it precisely frames any other widget of the same size. The widget color controls the color of the border. == Settings == The following settings are available specifically for Border Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Border&nbsp;Settings'''}} |- {{Setting|'''Line style'..." wikitext text/x-wiki The '''Border Widget''' displays a one-pixel-wide rectangular border. The border is rendered around the outside of the actual boundary of the widget so that it precisely frames any other widget of the same size. The widget color controls the color of the border. == Settings == The following settings are available specifically for Border Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Border&nbsp;Settings'''}} |- {{Setting|'''Line style'''|Determines whether the border is rendered as solid, dotted (with either one-pixel dots or two-pixel dots), or dashed.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/BorderWidget.html BorderWidget]</code> class [[Category:Interface]] a6f758b8fb242ab275d0cf168bc693f2c857ed44 Camera Widget 0 481 484 2023-07-15T12:33:51Z Eric Lengyel 1 Created page with "The '''Camera Widget''' displays a remote camera view in the world being played. It is only available for in-game panel effects. The widget color applies a tint to the entire camera view. == Settings == The following settings are available specifically for Camera Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Camera&nbsp;Settings'''}} |- {{Setting|'''Camera connector'''|Identifies a connector belonging to the panel effect node that is..." wikitext text/x-wiki The '''Camera Widget''' displays a remote camera view in the world being played. It is only available for in-game panel effects. The widget color applies a tint to the entire camera view. == Settings == The following settings are available specifically for Camera Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Camera&nbsp;Settings'''}} |- {{Setting|'''Camera connector'''|Identifies a connector belonging to the panel effect node that is connected to a camera node through which the camera view is rendered.}} |- {{Setting|'''Minimum detail level'''|Specifies the minimum detail level for both geometry and shaders at which objects are rendered through the camera. Higher numbers correspond to lower detail levels.}} |- {{Setting|'''Detail level bias'''|Specifies a bias that is added to the normal detail level for objects rendered through the camera. Positive values cause lower levels of detail to be rendered closer to the camera. This does not have to be an integer.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/CameraWidget.html CameraWidget]</code> class [[Category:Interface]] 45a02cbabf06bf2cc74c51ce8903fa572c1f4895 Check Widget 0 482 485 2023-07-15T12:34:18Z Eric Lengyel 1 Created page with "The '''Check Widget''' displays a check box that can be in the checked state or unchecked state. The widget color controls the color of the text. == Settings == The following settings are available specifically for Check Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Check&nbsp;Box&nbsp;Settings'''}} |- {{Setting|'''Initially checked'''|Determines whether the check box is initially in the checked state.}} |- {{Setting|'''Use highlight..." wikitext text/x-wiki The '''Check Widget''' displays a check box that can be in the checked state or unchecked state. The widget color controls the color of the text. == Settings == The following settings are available specifically for Check Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Check&nbsp;Box&nbsp;Settings'''}} |- {{Setting|'''Initially checked'''|Determines whether the check box is initially in the checked state.}} |- {{Setting|'''Use highlight when selected'''|Specifies that the check box changes to the highlight color when it is in the checked state.}} |- {{Setting|'''Text is not clickable'''|Specifies that clicking on the text has no effect and that the state of the check box can be changed only by clicking directly on the box.}} |- {{Setting|'''Button color'''|Specifies the color of the check box when it is not highlighted.}} |- {{Setting|'''Highlight color'''|If checked, specifies the color of the check box when it's in the selected state if the '''Use highlight when selected''' setting is checked, overriding the default highlight color specified by the <code>$hiliteColor</code> system variable.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/CheckWidget.html CheckWidget]</code> class [[Category:Interface]] 3a8861413b028e9987fe0f21894ead7e5827c7f0 Color Widget 0 483 486 2023-07-15T12:34:34Z Eric Lengyel 1 Created page with "The '''Color Widget''' displays a color selection box that displays a color picker dialog when clicked. The widget color controls the color of the color box's border. == Settings == The following settings are available specifically for Color Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Color&nbsp;Box&nbsp;Settings'''}} |- {{Setting|'''Initial color value'''|Specifies the color value to which the color box is initially set (the color..." wikitext text/x-wiki The '''Color Widget''' displays a color selection box that displays a color picker dialog when clicked. The widget color controls the color of the color box's border. == Settings == The following settings are available specifically for Color Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Color&nbsp;Box&nbsp;Settings'''}} |- {{Setting|'''Initial color value'''|Specifies the color value to which the color box is initially set (the color rendered in the interior).}} |- {{Setting|'''Color picker title'''|Specifies the title of the color picker window displayed when the user clicks inside the color box.}} |- {{Setting|'''Include alpha channel'''|Specifies whether the user is able to modify the alpha channel in the color picker.}} |- {{Setting|'''Focus glow color'''|If checked, specifies the color of the glow rendered when the color box is clicked, overriding the default glow color given by the <code>$buttonColor</code> system variable multiplied by 5/8.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/ColorWidget.html ColorWidget]</code> class [[Category:Interface]] 4db6ca9a2933d66c7dec37f91839921e1e884340 Configuration Widget 0 484 487 2023-07-15T12:34:52Z Eric Lengyel 1 Created page with "The '''Configuration Widget''' displays a configuration table that is used to show property settings to the user. The widget color controls the color of the configuration table's border. == Settings == The following settings are available specifically for Configuration Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Configuration&nbsp;Settings'''}} |- {{Setting|'''Title column fraction'''|Determines what fraction of the full width of th..." wikitext text/x-wiki The '''Configuration Widget''' displays a configuration table that is used to show property settings to the user. The widget color controls the color of the configuration table's border. == Settings == The following settings are available specifically for Configuration Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Configuration&nbsp;Settings'''}} |- {{Setting|'''Title column fraction'''|Determines what fraction of the full width of the table is used for the setting titles. A vertical line is rendered in between the title column and value column in the table.}} |- {{Setting|'''Show script variable column'''|Used by the [[Script Editor]] to indicate that a third column be shown for variable name entry.}} |- {{Setting|'''Line color'''|If checked, specifies the color of the border lines inside the configuration table, overriding the default color given by the average of 50% gray and the window frame color given by the <code>$windowFrameColor</code> system variable.}} |- {{Setting|'''Background color'''|Specifies the background color for the configuration table.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/ConfigurationWidget.html ConfigurationWidget]</code> class [[Category:Interface]] 8f121298935e1ca3164f54749b81d8827e9d835a Edit Text Widget 0 485 488 2023-07-15T12:35:14Z Eric Lengyel 1 Created page with "The '''Edit Text Widget''' displays an editable text box that allows a single line or multiple lines of text entry. The widget color controls the color of the text. == Settings == The following settings are available specifically for Edit Text Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Edit&nbsp;Text&nbsp;Settings'''}} |- {{Setting|'''Maximum length'''|Specifies the maximum number of characters that can be entered into the text box..." wikitext text/x-wiki The '''Edit Text Widget''' displays an editable text box that allows a single line or multiple lines of text entry. The widget color controls the color of the text. == Settings == The following settings are available specifically for Edit Text Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Edit&nbsp;Text&nbsp;Settings'''}} |- {{Setting|'''Maximum length'''|Specifies the maximum number of characters that can be entered into the text box.}} |- {{Setting|'''Character filter'''|Specifies a filter that determines what types of characters can be entered into the text box: * The value '''None''' means that any characters can be entered. * The value '''Numbers''' means that only the digits 0 through 9 can be entered. * The value '''Signed numbers''' means that only the digits 0 through 9 and a minus sign can be entered. * The value '''Floating-point''' means that any floating-point number can be entered, including an exponent. * The value '''Alphanumeric''' means that only uppercase letters, lowercase letters, and the digits 0 through 9 can be entered. * The value '''Identifier''' means that only uppercase letters, lowercase letters, the digits 0 through 9, and the underscore character can be entered.}} |- {{Setting|'''Allow text to overflow'''|Specifies whether the width of the text can exceed the width of the text box (with scrolling).}} |- {{Setting|'''Use multiple lines'''|Specifies whether the text box renders multiple lines or just a single line of text.}} |- {{Setting|'''Text is read-only'''|Specifies that the user cannot change the text in the text box, but can still select and copy parts of it.}} |- {{Setting|'''Select all when changed'''|Causes the text box to automatically select all when its text is changed through a method other than user input.}} |- {{Setting|'''Select all on double-click'''|Causes a double-click in the text box to select all, whereas a double-click would normally select only the word that was clicked on.}} |- {{Setting|'''Render plain (text only)'''|Causes the border, background, and keyboard focus glow to not be rendered.}} |- {{Setting|'''Render focus plain (no glow)'''|Causes the keyboard focus glow to not be rendered (but the border and background are still shown).}} |- {{Setting|'''Background color'''|Specifies the color of the text box's background.}} |- {{Setting|'''Border color'''|Specifies the color of the text box's border.}} |- {{Setting|'''Highlight color'''|If checked, specifies the highlight color for selected text, overriding the default highlight color given by the <code>$hiliteColor</code> system variable.}} |- {{Setting|'''Focus glow color'''|If checked, specifies the color of the glow rendered when the editable text box has the keyboard focus, overriding the default glow color given by the <code>$hiliteColor</code> system variable multiplied by 5/8.}} |- {{Setting|'''Insertion caret color'''|Specifies the color of the insertion caret.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/EditTextWidget.html EditTextWidget]</code> class [[Category:Interface]] e73cc3f08f52f75855f9b0e3e2d4f4199481daa5 Frustum Viewport Widget 0 486 489 2023-07-15T12:35:35Z Eric Lengyel 1 Created page with "The '''Frustum Viewport Widget''' displays a viewport having a frustum camera. The widget color is not used. == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/FrustumViewportWidget.html FrustumViewportWidget]</code> class [[Category:Interface]]" wikitext text/x-wiki The '''Frustum Viewport Widget''' displays a viewport having a frustum camera. The widget color is not used. == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/FrustumViewportWidget.html FrustumViewportWidget]</code> class [[Category:Interface]] 80df82afc9ddcf7cbfca550af7904b7b08e99677 Hyperlink Widget 0 487 490 2023-07-15T12:35:57Z Eric Lengyel 1 Created page with "The '''Hyperlink Widget''' displays a text button with a hyperlink. Clicking on the button opens the default web browser installed on the user's computer and navigates to the address stored in the widget. The widget color controls the color of the text. == Settings == The following settings are available specifically for Hyperlink Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Hyperlink&nbsp;Settings'''}} |- {{Setting|'''Hyperlink URL'..." wikitext text/x-wiki The '''Hyperlink Widget''' displays a text button with a hyperlink. Clicking on the button opens the default web browser installed on the user's computer and navigates to the address stored in the widget. The widget color controls the color of the text. == Settings == The following settings are available specifically for Hyperlink Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Hyperlink&nbsp;Settings'''}} |- {{Setting|'''Hyperlink URL'''|Specifies the link sent to the user's browser when the text button is activated.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/HyperlinkWidget.html HyperlinkWidget]</code> class [[Category:Interface]] 50144d2d0246c2beb0fce726609ba90d120fdfb5 File:Widget iconbutton.png 6 488 491 2023-07-15T12:37:50Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Icon Widget 0 489 492 2023-07-15T12:38:58Z Eric Lengyel 1 Created page with "The '''Icon Widget''' displays a vector-based icon stored in an album resource. An icon widget is drawn using the [[Slug Library]]. The widget color controls the color of a monochrome icon but is not used for a multicolor icon. == Settings == The following settings are available specifically for Icon Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Icon&nbsp;Settings'''}} |- {{Setting|'''Album'''|Specifies the album resource containing t..." wikitext text/x-wiki The '''Icon Widget''' displays a vector-based icon stored in an album resource. An icon widget is drawn using the [[Slug Library]]. The widget color controls the color of a monochrome icon but is not used for a multicolor icon. == Settings == The following settings are available specifically for Icon Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Icon&nbsp;Settings'''}} |- {{Setting|'''Album'''|Specifies the album resource containing the icon.}} |- {{Setting|'''Icon&nbsp;index'''|Specifies the index of the icon within the album.}} |- {{Setting|'''Scale&nbsp;to&nbsp;fit'''|If enabled, scales the icon to the largest size that fits within the widget's bounding box without changing the icon's aspect ratio.}} |- {{HeadingSetting|'''Icon&nbsp;Rendering&nbsp;Settings'''}} |- {{Setting|'''Render&nbsp;multicolor&nbsp;icon'''|Determines whether the icon is monochrome or multicolor.}} |- {{Setting|'''Render&nbsp;with&nbsp;optical&nbsp;weight'''|Specifies that the coverage values calculated on the boundaries of an icon are to be increased for heavier appearance. As with text, this is used to improve visibility of small details.}} |- {{Setting|'''Render&nbsp;symmetric&nbsp;band&nbsp;splits'''|Specifies whether the band-split optimization is applied to the icon. This setting reduces rendering time by using curve lists sorted in opposite orders for the negative and positive halves of each band in an icon. This has no effect on the visual appearance of an icon, but it can increase performance for icons rendered at large sizes. This can have a negative effect on performance when icons are rendered at small sizes, so it should not be enabled in those cases.}} |- {{Setting|'''Render&nbsp;adaptive&nbsp;supersampling'''|Specifies whether icons are rendered with adaptive supersampling for high quality at very small sizes.}} |- {{Setting|'''Use&nbsp;bounding&nbsp;polygons'''|Specifies whether the bounding polygon optimization is enabled for the icon. This setting reduces the number of pixels covered by the icon by using a tight polygon with 3&ndash;6 sides instead of a quad. This has no effect on the visual appearance of an icon, but it can increase performance for icons rendered at large sizes. This can have a ''negative'' effect on performance when icons are rendered at small sizes, so it should not be enabled in those cases.}} |- {{Setting|'''Use&nbsp;rectangle&nbsp;optimization'''|Specifies that the icon is to be rendered as a rectangle primitive, if supported by the hardware. This optimization should be enabled only for an icon that is known to always be rendered aligned to the screen axes.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/IconWidget.html IconWidget]</code> class [[Category:Interface]] 22d09c75f5958908b217f35711436220f59f9692 Picture Widget 0 490 493 2023-07-15T12:39:35Z Eric Lengyel 1 Created page with "The '''Picture Widget''' displays a vector-based picture stored in an album resource. A picture widget is drawn using the [[Slug Library]]. The widget color is not used. == Settings == The following settings are available specifically for Picture Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Picture&nbsp;Settings'''}} |- {{Setting|'''Album'''|Specifies the album resource containing the picture.}} |- {{Setting|'''Picture&nbsp;index'''|..." wikitext text/x-wiki The '''Picture Widget''' displays a vector-based picture stored in an album resource. A picture widget is drawn using the [[Slug Library]]. The widget color is not used. == Settings == The following settings are available specifically for Picture Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Picture&nbsp;Settings'''}} |- {{Setting|'''Album'''|Specifies the album resource containing the picture.}} |- {{Setting|'''Picture&nbsp;index'''|Specifies the index of the picture within the album.}} |- {{Setting|'''Scale&nbsp;to&nbsp;fit'''|If enabled, scales the picture to the largest size that fits within the widget's bounding box without changing the picture's aspect ratio.}} |- {{HeadingSetting|'''Picture&nbsp;Rendering&nbsp;Settings'''}} |- {{Setting|'''Render&nbsp;with&nbsp;optical&nbsp;weight'''|Specifies that the coverage values calculated on the boundaries of a picture are to be increased for heavier appearance. As with text, this is used to improve visibility of small details.}} |- {{Setting|'''Render&nbsp;symmetric&nbsp;band&nbsp;splits'''|Specifies whether the band-split optimization is applied to the picture. This setting reduces rendering time by using curve lists sorted in opposite orders for the negative and positive halves of each band in a component. This has no effect on the visual appearance of a picture, but it can increase performance for pictures rendered at large sizes. This can have a negative effect on performance when pictures are rendered at small sizes, so it should not be enabled in those cases.}} |- {{Setting|'''Render&nbsp;adaptive&nbsp;supersampling'''|Specifies whether the picture is rendered with adaptive supersampling for high quality at very small sizes.}} |- {{Setting|'''Render&nbsp;linear&nbsp;curve&nbsp;optimization'''|Enables an optimization that allows pictures with many polygonal components to be rendered faster.}} |- {{Setting|'''Use&nbsp;bounding&nbsp;polygons'''|Specifies whether the bounding polygon optimization is enabled for the picture. This setting reduces the number of pixels covered by each component by using a tight polygon with 3&ndash;6 sides instead of a quad. This has no effect on the visual appearance of a picture, but it can increase performance for pictures rendered at large sizes. This can have a ''negative'' effect on performance when picture are rendered at small sizes, so it should not be enabled in those cases.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/PictureWidget.html PictureWidget]</code> class [[Category:Interface]] e89d316dd8ef9651e152870af5182fea8d6d04af Icon Button Widget 0 491 495 2023-07-15T12:40:58Z Eric Lengyel 1 Created page with "The '''Icon Button Widget''' displays a button with a texture image. The widget color applies to the texture image displayed in the button. == Settings == The following settings are available specifically for Icon Button Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Icon&nbsp;Button&nbsp;Settings'''}} |- {{Setting|'''Stays selected when clicked'''|Causes the button to remain in the selected state when it is clicked.}} |- {{Setting|'''..." wikitext text/x-wiki The '''Icon Button Widget''' displays a button with a texture image. The widget color applies to the texture image displayed in the button. == Settings == The following settings are available specifically for Icon Button Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Icon&nbsp;Button&nbsp;Settings'''}} |- {{Setting|'''Stays selected when clicked'''|Causes the button to remain in the selected state when it is clicked.}} |- {{Setting|'''Render plain (icon only)'''|Specifies that the button background is not rendered.}} |- {{Setting|'''Initially selected'''|Specifies that the button is initially in the selected state.}} |- {{Setting|'''Button color'''|Specifies the color of the button itself (without affecting the icon image).}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/IconButtonWidget.html IconButtonWidget]</code> class [[Category:Interface]] f34f73d90b2bfe66cbe91d23ea2422a37af3b611 Image Widget 0 492 496 2023-07-15T12:41:24Z Eric Lengyel 1 Created page with "The '''Image Widget''' displays a plain texture image. The widget color applies a tint to the texture image. == Settings == The following settings are available specifically for Image Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Image&nbsp;Settings'''}} |- {{Setting|'''Texture map'''|Specifies the texture resource that is displayed by the widget.}} |- {{Setting|'''X scale'''|Applies a horizontal scale to the texture image.}} |- {{Set..." wikitext text/x-wiki The '''Image Widget''' displays a plain texture image. The widget color applies a tint to the texture image. == Settings == The following settings are available specifically for Image Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Image&nbsp;Settings'''}} |- {{Setting|'''Texture map'''|Specifies the texture resource that is displayed by the widget.}} |- {{Setting|'''X scale'''|Applies a horizontal scale to the texture image.}} |- {{Setting|'''Y scale'''|Aapplies a vertical scale to the texture image.}} |- {{Setting|'''X offset'''|Applies a horizontal offset to the texture image.}} |- {{Setting|'''Y offset'''|Applies a vertical offset to the texture image.}} |- {{Setting|'''Blend mode'''|Specifies the blending mode for the texture image: * The value '''Add''' causes the image to be added to the background. * The value '''Alpha add''' causes the image to be multiplied by its alpha channel and then added to the background. * The value '''Alpha blend''' causes the image to be multiplied by its alpha channel and then added to the background multiplied by the inverse of the image's alpha channel. * The value '''Alpha preblend''' causes the image to be added to the background multiplied by the inverse of the image's alpha channel. * The value '''Replace''' causes the image to replace the background with no blending.}} |- {{Setting|'''Layer/depth coordinate'''|Applies only to 2D array textures are 3D textures, and it specifies the layer or depth coordinate used to display the image.}} |- {{Setting|'''Cube map face index'''|Applies only to cube map textures, and it specifies which face is displayed by the image widget.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/ImageWidget.html ImageWidget]</code> class [[Category:Interface]] 1773dd62e2a2d3e0eb2bc07ee88397ca3ba5983f Image Button Widget 0 493 497 2023-07-15T12:42:04Z Eric Lengyel 1 Created page with "The '''Image Button Widget''' displays a button with a texture image. The widget color applies to the texture image displayed in the button. == Settings == The following settings are available specifically for Image Button Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Image&nbsp;Button&nbsp;Settings'''}} |- {{Setting|'''Stays selected when clicked'''|Causes the button to remain in the selected state when it is clicked.}} |- {{Setting|..." wikitext text/x-wiki The '''Image Button Widget''' displays a button with a texture image. The widget color applies to the texture image displayed in the button. == Settings == The following settings are available specifically for Image Button Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Image&nbsp;Button&nbsp;Settings'''}} |- {{Setting|'''Stays selected when clicked'''|Causes the button to remain in the selected state when it is clicked.}} |- {{Setting|'''Render plain (image only)'''|Specifies that the button background is not rendered.}} |- {{Setting|'''Initially selected'''|Specifies that the button is initially in the selected state.}} |- {{Setting|'''Button color'''|Specifies the color of the button itself (without affecting the image).}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/ImageButtonWidget.html ImageButtonWidget]</code> class [[Category:Interface]] 237f7f6adb3670491e84449633ad2a374da13c0a Line Widget 0 494 498 2023-07-15T12:42:31Z Eric Lengyel 1 Created page with "The '''Line Widget''' displays a one-pixel-wide line that can be solid, dotted, or dashed. The widget color controls the color of the line. == Settings == The following settings are available specifically for Line Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Line&nbsp;Settings'''}} |- {{Setting|'''Line style'''|Determines whether the line is rendered as solid, dotted (with either one-pixel dots or two-pixel dots), or dashed.}} |} ==..." wikitext text/x-wiki The '''Line Widget''' displays a one-pixel-wide line that can be solid, dotted, or dashed. The widget color controls the color of the line. == Settings == The following settings are available specifically for Line Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Line&nbsp;Settings'''}} |- {{Setting|'''Line style'''|Determines whether the line is rendered as solid, dotted (with either one-pixel dots or two-pixel dots), or dashed.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/LineWidget.html LineWidget]</code> class [[Category:Interface]] 55a103582a43c8e93662004de7a2836acf5b8bd7 List Widget 0 495 499 2023-07-15T12:42:55Z Eric Lengyel 1 Created page with "The '''List Widget''' displays a list box with a scroll bar. The widget color controls the color of the list's border. == Settings == The following settings are available specifically for List Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''List&nbsp;Settings'''}} |- {{Setting|'''Item spacing'''|Specifies the vertical distance from one list item to the next. The height of the list box should be a multiple of this value to avoid extra sp..." wikitext text/x-wiki The '''List Widget''' displays a list box with a scroll bar. The widget color controls the color of the list's border. == Settings == The following settings are available specifically for List Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''List&nbsp;Settings'''}} |- {{Setting|'''Item spacing'''|Specifies the vertical distance from one list item to the next. The height of the list box should be a multiple of this value to avoid extra space at the bottom of the list.}} |- {{Setting|'''Item offset X'''|Specifies a horizontal offset for items displayed in the list.}} |- {{Setting|'''Item offset Y'''|Specifies a vertical offset for items displayed in the list.}} |- {{Setting|'''Allow multiple selection'''|Enables multiple items to be selected in the list at the same time.}} |- {{Setting|'''Render focus plain (no glow)'''|Causes the keyboard focus glow to not be rendered.}} |- {{Setting|'''Leave list items enabled'''|Causes items in the list to be left in an enabled state to allow user interaction directly with each item.}} |- {{Setting|'''Background color'''|Specifies the color of the list background.}} |- {{Setting|'''Highlight color'''|If checked, specifies the color of the highlight used to indicate selected items, overriding the default highlight color specified by the <code>$hiliteColor</code> system variable.}} |- {{Setting|'''Focus glow color'''|If checked, specifies the color of the glow drawn around the list box when it has the keyboard focus, overriding the default glow color given by the <code>$hiliteColor</code> system variable multiplied by 5/8.}} |- {{Setting|'''Text item font'''|Determines what font is used to display plain text list items.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/ListWidget.html ListWidget]</code> class [[Category:Interface]] 3b435e81e47ed273b94b9f4491e5db7157e15b99 Menu Bar Widget 0 496 500 2023-07-15T12:43:16Z Eric Lengyel 1 Created page with "The '''Menu Bar Widget''' displays a menu bar that allows the user to choose commands from pull-down menus. The widget color applies a tint to the menu bar. == Settings == The following settings are available specifically for Menu Bar Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Menu&nbsp;Bar&nbsp;Settings'''}} |- {{Setting|'''Menu title font'''|Determines what font is used to display menu titles.}} |- {{Setting|'''Menu title font si..." wikitext text/x-wiki The '''Menu Bar Widget''' displays a menu bar that allows the user to choose commands from pull-down menus. The widget color applies a tint to the menu bar. == Settings == The following settings are available specifically for Menu Bar Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Menu&nbsp;Bar&nbsp;Settings'''}} |- {{Setting|'''Menu title font'''|Determines what font is used to display menu titles.}} |- {{Setting|'''Menu title font size'''|Specifies the font size for menu titles.}} |- {{Setting|'''Menu title spacing'''|Specifies how much horizontal space is inserted between menu titles.}} |- {{Setting|'''Menu title offset Y'''|Specifies the vertical offset for menu titles.}} |- {{Setting|'''Highlight color'''|If checked, specifies the highlight color for the selected menu name, overriding the default highlight color given by the <code>$hiliteColor</code> system variable.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/MenuBarWidget.html MenuBarWidget]</code> class [[Category:Interface]] 757c4e8771b222c2b9cbd139fe48d1b2bb133d08 Movie Widget 0 497 501 2023-07-15T12:43:33Z Eric Lengyel 1 Created page with "The '''Movie Widget''' plays a movie resource. The widget color applies a tint to the entire movie image. == Settings == The following settings are available specifically for Movie Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Movie&nbsp;Settings'''}} |- {{Setting|'''Movie name'''|Specifies the resource name of the movie.}} |- {{Setting|'''Movie is initially playing'''|Causes the movie to start playing when the panel is loaded.}} |- {..." wikitext text/x-wiki The '''Movie Widget''' plays a movie resource. The widget color applies a tint to the entire movie image. == Settings == The following settings are available specifically for Movie Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Movie&nbsp;Settings'''}} |- {{Setting|'''Movie name'''|Specifies the resource name of the movie.}} |- {{Setting|'''Movie is initially playing'''|Causes the movie to start playing when the panel is loaded.}} |- {{Setting|'''Movie is looping'''|Causes the movie to loop.}} |- {{Setting|'''Movie blend mode'''|Specifies the blending mode for the movie image. This setting pertains only to movies that contain an alpha channel. See the [[Image Widget]] for the meaning of the blending modes.}} |- {{Setting|'''Source connector key'''|Identifies a connector belonging to the panel effect node that is connected to a source node through which the movie audio is played. This setting pertains only to movie widgets belonging to in-game panel effects.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/MovieWidget.html MovieWidget]</code> class [[Category:Interface]] [[Category:Movies]] 7c5e377c26a5a371ff81ea1a97539126cd227fcd Category:Interface 14 498 502 2023-07-15T12:43:41Z Eric Lengyel 1 Created blank page wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Category:Movies 14 499 503 2023-07-15T12:43:48Z Eric Lengyel 1 Created blank page wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Multipane Widget 0 500 504 2023-07-15T12:44:08Z Eric Lengyel 1 Created page with "The '''Multipane Widget''' displays a multipane box. The border and selection tabs are displayed outside the actual boundary of the widget. The widget color controls the color of the border. == Settings == The following settings are available specifically for Multipane Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Multipane&nbsp;Settings'''}} |- {{Setting|'''Line style'''|Determines whether the border is rendered as solid, dotted (wit..." wikitext text/x-wiki The '''Multipane Widget''' displays a multipane box. The border and selection tabs are displayed outside the actual boundary of the widget. The widget color controls the color of the border. == Settings == The following settings are available specifically for Multipane Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Multipane&nbsp;Settings'''}} |- {{Setting|'''Line style'''|Determines whether the border is rendered as solid, dotted (with either one-pixel dots or two-pixel dots), or dashed.}} |- {{Setting|'''Pane title font'''|Determines what font is used to display pane titles.}} |- {{Setting|'''Pane list'''|Specifies the list of pane titles, where each title is separated from the next by a semicolon.}} |- {{Setting|'''Initial selection'''|Determines which pane is initially selected. A value of &minus;1 indicates that no pane is selected.}} |- {{Setting|'''Button color'''|Controls the color of the pane tabs.}} |- {{Setting|'''Highlight color'''|If checked, controls the color of the selected pane tab, overriding the default highlight color specified by the <code>$hiliteColor</code> system variable.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/MultipaneWidget.html MultipaneWidget]</code> class [[Category:Interface]] d9a3d1f0976c99c897eac2c8c0a7af7cb57a2184 Ortho Viewport Widget 0 501 505 2023-07-15T12:44:31Z Eric Lengyel 1 Created page with "The '''Ortho Viewport Widget''' displays a viewport having an orthographic camera. The widget color is not used. == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/OrthoViewportWidget.html OrthoViewportWidget]</code> class [[Category:Interface]]utf-8�‚… 0�  �5 )š« ���hThe '''Paint Widget''' displays an interactive painting canvas. The brush radius, fuzziness, opacity, and color can be set from a script using controlle..." wikitext text/x-wiki The '''Ortho Viewport Widget''' displays a viewport having an orthographic camera. The widget color is not used. == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/OrthoViewportWidget.html OrthoViewportWidget]</code> class [[Category:Interface]]utf-8�‚… 0�  �5 )š« ���hThe '''Paint Widget''' displays an interactive painting canvas. The brush radius, fuzziness, opacity, and color can be set from a script using controller functions. The widget color applies a tint to the contents of the painting canvas. == Settings == The following settings are available specifically for Paint Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Paint&nbsp;Settings'''}} |- {{Setting|'''Resolution X'''|Determines the internal horizontal resolution of the painting canvas, in pixels.}} |- {{Setting|'''Resolution Y'''|Determines the internal vertical resolution of the painting canvas, in pixels.}} |- {{Setting|'''Background color'''|Determines what color the painting canvas is initially filled with.}} |- {{Setting|'''Initial brush radius'''|Specifies the initial radius of the paint brush, in pixels.}} |- {{Setting|'''Initial brush fuzziness'''|Specifies the initial fuzziness of the paint brush in the range 0.0 (no fuzziness) to 1.0 (very fuzzy).}} |- {{Setting|'''Initial brush opacity'''|Specifies the initial opacity of the paint brush in the range 1% (almost completely transparent) to 100% (completely opaque).}} |- {{Setting|'''Initial brush color'''|Specifies the initial color of the paint brush.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/PaintWidget.html PaintWidget]</code> class [[Category:Interface]] bb85844d915091034d8ae741fff6d273603cf884 506 505 2023-07-15T12:44:54Z Eric Lengyel 1 wikitext text/x-wiki The '''Ortho Viewport Widget''' displays a viewport having an orthographic camera. The widget color is not used. == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/OrthoViewportWidget.html OrthoViewportWidget]</code> class [[Category:Interface]] cc656a7902ab13eb8dd205b264658c102b7247ea Paint Widget 0 502 507 2023-07-15T12:45:22Z Eric Lengyel 1 Created page with "The '''Paint Widget''' displays an interactive painting canvas. The brush radius, fuzziness, opacity, and color can be set from a script using controller functions. The widget color applies a tint to the contents of the painting canvas. == Settings == The following settings are available specifically for Paint Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Paint&nbsp;Settings'''}} |- {{Setting|'''Resolution X'''|Determines the internal..." wikitext text/x-wiki The '''Paint Widget''' displays an interactive painting canvas. The brush radius, fuzziness, opacity, and color can be set from a script using controller functions. The widget color applies a tint to the contents of the painting canvas. == Settings == The following settings are available specifically for Paint Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Paint&nbsp;Settings'''}} |- {{Setting|'''Resolution X'''|Determines the internal horizontal resolution of the painting canvas, in pixels.}} |- {{Setting|'''Resolution Y'''|Determines the internal vertical resolution of the painting canvas, in pixels.}} |- {{Setting|'''Background color'''|Determines what color the painting canvas is initially filled with.}} |- {{Setting|'''Initial brush radius'''|Specifies the initial radius of the paint brush, in pixels.}} |- {{Setting|'''Initial brush fuzziness'''|Specifies the initial fuzziness of the paint brush in the range 0.0 (no fuzziness) to 1.0 (very fuzzy).}} |- {{Setting|'''Initial brush opacity'''|Specifies the initial opacity of the paint brush in the range 1% (almost completely transparent) to 100% (completely opaque).}} |- {{Setting|'''Initial brush color'''|Specifies the initial color of the paint brush.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/PaintWidget.html PaintWidget]</code> class [[Category:Interface]] e5a21d64dcbbb2eabd3b7f7632b47a6856e69dfc Password Widget 0 503 508 2023-07-15T12:45:46Z Eric Lengyel 1 Created page with "The '''Password Widget''' displays a password entry box that obscures the text entered into it. The widget color controls the color of the text. == Settings == The following settings are available specifically for Password Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Password&nbsp;Settings'''}} |- {{Setting|'''Enable security features'''|Specifies that extra steps be taken to ensure the security of the password text. In particular, w..." wikitext text/x-wiki The '''Password Widget''' displays a password entry box that obscures the text entered into it. The widget color controls the color of the text. == Settings == The following settings are available specifically for Password Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Password&nbsp;Settings'''}} |- {{Setting|'''Enable security features'''|Specifies that extra steps be taken to ensure the security of the password text. In particular, when this box is checked, the memory used to hold the password is locked in physical RAM and cannot be written to the system page file, and the password is erased before the widget is destroyed.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/PasswordWidget.html PasswordWidget]</code> class [[Category:Interface]] 5d418bc9ed15e96890c1286c0725b6646b528ad6 Popup Menu Widget 0 504 509 2023-07-15T12:46:11Z Eric Lengyel 1 Created page with "The '''Popup Menu Widget''' displays a popup menu. The widget color controls the color of the text. == Settings == The following settings are available specifically for Popup Menu Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Popup&nbsp;Menu&nbsp;Settings'''}} |- {{Setting|'''Render plain (text only)'''|Causes the background button not to be rendered.}} |- {{Setting|'''Item spacing'''|Specifies the vertical distance from one menu item..." wikitext text/x-wiki The '''Popup Menu Widget''' displays a popup menu. The widget color controls the color of the text. == Settings == The following settings are available specifically for Popup Menu Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Popup&nbsp;Menu&nbsp;Settings'''}} |- {{Setting|'''Render plain (text only)'''|Causes the background button not to be rendered.}} |- {{Setting|'''Item spacing'''|Specifies the vertical distance from one menu item to the next.}} |- {{Setting|'''Menu item list'''|Specifies the list of menu items, where each item is separated from the next by a semicolon.}} |- {{Setting|'''Initial selection'''|Determines which menu item is initially selected. A value of &minus;1 indicates that no item is selected, in which case the text string is displayed, if specified.}} |- {{Setting|'''Button color'''|Specifies the color of the background button.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/PopupMenuWidget.html PopupMenuWidget]</code> class [[Category:Interface]] 2ce53f741662d5baaa77972ac441a93750f02d38 Progress Widget 0 505 510 2023-07-15T12:46:37Z Eric Lengyel 1 Created page with "The '''Progress Widget''' displays a progress bar. The widget color controls the color of the background of the progress bar that is shown for the uncompleted portion of progress. == Settings == The following settings are available specifically for Progress Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Progress&nbsp;Bar&nbsp;Settings'''}} |- {{Setting|'''Render plain (no border)'''|Specifies that the progress bar is rendered without a..." wikitext text/x-wiki The '''Progress Widget''' displays a progress bar. The widget color controls the color of the background of the progress bar that is shown for the uncompleted portion of progress. == Settings == The following settings are available specifically for Progress Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Progress&nbsp;Bar&nbsp;Settings'''}} |- {{Setting|'''Render plain (no border)'''|Specifies that the progress bar is rendered without a border and at the full height of the widget bounds.}} |- {{Setting|'''Initial value'''|Specifies the initial value of the progress bar.}} |- {{Setting|'''Maximum value'''|Specifies the maximum value of the progress bar.}} |- {{Setting|'''Highlight color'''|If checked, specifies the highlight color for the progress bar that is shown for the completed portion of progress, overriding the default highlight color specified by the <code>$hiliteColor</code> system variable.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/ProgressWidget.html ProgressWidget]</code> class [[Category:Interface]] 672700826074c3d6537c18a2591442ed6a79a49c Push Button Widget 0 506 511 2023-07-15T12:47:05Z Eric Lengyel 1 Created page with "The '''Push Button Widget''' displays a button with a text string. The widget color controls the color of the text. == Settings == The following settings are available specifically for Push Button Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Push&nbsp;Button&nbsp;Settings'''}} |- {{Setting|'''Primary button'''|Indicates that the button should be rendered with the appearance of a primary button, which causes the color of the button be..." wikitext text/x-wiki The '''Push Button Widget''' displays a button with a text string. The widget color controls the color of the text. == Settings == The following settings are available specifically for Push Button Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Push&nbsp;Button&nbsp;Settings'''}} |- {{Setting|'''Primary button'''|Indicates that the button should be rendered with the appearance of a primary button, which causes the color of the button be that specified by the <code>$buttonColor</code> system variable.}} |- {{Setting|'''Activation key'''|Specifies whether the Enter or Escape key acts as a shortcut for the push button.}} |- {{Setting|'''Button color'''|Specifies the color of the push button if it is not a primary button.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/PushButtonWidget.html PushButtonWidget]</code> class [[Category:Interface]] 618fd543e0fafa5ff7089fd7f912b13d66e804ad Quad Widget 0 507 512 2023-07-15T12:47:25Z Eric Lengyel 1 Created page with "The '''Quad Widget''' displays a plain colored quad. The widget color controls the color of the quad. == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/QuadWidget.html QuadWidget]</code> class [[Category:Interface]]" wikitext text/x-wiki The '''Quad Widget''' displays a plain colored quad. The widget color controls the color of the quad. == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/QuadWidget.html QuadWidget]</code> class [[Category:Interface]] 1ca224966895a54829ea806b4c79032a7e3c4da0 Radio Widget 0 508 513 2023-07-15T12:47:49Z Eric Lengyel 1 Created page with "The '''Radio Widget''' displays a radio button that can be in the selected or unselected state. When a radio button is selected, all other radio buttons in the same group (or in the entire window if the radio button is not in a group) are automatically unselected. The widget color controls the color of the text. == Settings == The following settings are available specifically for Radio Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Rad..." wikitext text/x-wiki The '''Radio Widget''' displays a radio button that can be in the selected or unselected state. When a radio button is selected, all other radio buttons in the same group (or in the entire window if the radio button is not in a group) are automatically unselected. The widget color controls the color of the text. == Settings == The following settings are available specifically for Radio Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Radio&nbsp;Button&nbsp;Settings'''}} |- {{Setting|'''Initially selected'''|Determines whether the radio button is initially in the selected state.}} |- {{Setting|'''Use highlight when selected'''|Specifies that the radio button changes to the highlight color when it is in the selected state.}} |- {{Setting|'''Text is not clickable'''|Specifies that clicking on the text has no effect and that the state of the radio button can be changed only by clicking directly on the button.}} |- {{Setting|'''Button color'''|Specifies the color of the radio button when it is not highlighted.}} |- {{Setting|'''Highlight color'''|If checked, specifies the color of the radio button when it's in the selected state if the Use highlight when selected setting is checked, overriding the default highlight color specified by the <code>$hiliteColor</code> system variable.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/RadioWidget.html RadioWidget]</code> class [[Category:Interface]] 8c65d33c540d1d22bebd7d491bc5a1fad0d83240 Scroll Widget 0 509 514 2023-07-15T12:48:12Z Eric Lengyel 1 Created page with "The '''Scroll Widget''' displays a scroll bar. The widget color controls the color of the scroll bar's background. == Settings == The following settings are available specifically for Scroll Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Scroll&nbsp;Bar&nbsp;Settings'''}} |- {{Setting|'''Horizontal appearance'''|Causes the widget to be rendered with the appearance adjusted for a horizontally-oriented scroll bar.}} |- {{Setting|'''Initi..." wikitext text/x-wiki The '''Scroll Widget''' displays a scroll bar. The widget color controls the color of the scroll bar's background. == Settings == The following settings are available specifically for Scroll Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Scroll&nbsp;Bar&nbsp;Settings'''}} |- {{Setting|'''Horizontal appearance'''|Causes the widget to be rendered with the appearance adjusted for a horizontally-oriented scroll bar.}} |- {{Setting|'''Initial value'''|Specifies the initial value for the scroll bar.}} |- {{Setting|'''Maximum value'''|Specifies the maximum value for the scroll bar.}} |- {{Setting|'''Page up/down distance'''|Specifies by how much the value changes when the user clicks in the scroll bar above or below the indicator button.}} |- {{Setting|'''Button color'''|Specifies the color of the up, down, and indicator buttons.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/ScrollWidget.html ScrollWidget]</code> class [[Category:Interface]] bd7ae1e53aede7ac79e62b24ac674282f6d24b07 Slider Widget 0 510 515 2023-07-15T12:49:03Z Eric Lengyel 1 Created page with "The '''Slider Widget''' displays a slider. The widget color controls the color of the slider bar. == Settings == The following settings are available specifically for Slider Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Slider&nbsp;Settings'''}} |- {{Setting|'''Slider style'''|Determines the style of the indicator button, and it can be circular or square.}} |- {{Setting|'''Initial value'''|Specifies the initial value for the slider.}}..." wikitext text/x-wiki The '''Slider Widget''' displays a slider. The widget color controls the color of the slider bar. == Settings == The following settings are available specifically for Slider Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Slider&nbsp;Settings'''}} |- {{Setting|'''Slider style'''|Determines the style of the indicator button, and it can be circular or square.}} |- {{Setting|'''Initial value'''|Specifies the initial value for the slider.}} |- {{Setting|'''Maximum value'''|Specifies the maximum value for the slider.}} |- {{Setting|'''Button color'''|If checked, specifies the color of the indicator button, overriding the default button color specified by the <code>$buttonColor</code> system variable.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/SliderWidget.html SliderWidget]</code> class [[Category:Interface]] 1675a07fcd55ca498f7020e6a586cc7581c3777c Stroke Widget 0 511 516 2023-07-15T12:49:41Z Eric Lengyel 1 Created page with "The '''Stroke Widget''' displays a vector-based line that can have cap styles and dashing. A stroke widget is drawn using the [[Slug Library]]. The widget color controls the color of the stroke. == Settings == The following settings are available specifically for Stroke Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Stroke&nbsp;Settings'''}} |- {{Setting|'''Stroke&nbsp;thickness'''|Specifies the thickness of the stroke, in pixels.}} |-..." wikitext text/x-wiki The '''Stroke Widget''' displays a vector-based line that can have cap styles and dashing. A stroke widget is drawn using the [[Slug Library]]. The widget color controls the color of the stroke. == Settings == The following settings are available specifically for Stroke Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Stroke&nbsp;Settings'''}} |- {{Setting|'''Stroke&nbsp;thickness'''|Specifies the thickness of the stroke, in pixels.}} |- {{Setting|'''Stroke&nbsp;caps'''|Determines what style of caps are drawn for the stroke. This can be one of the following values: * '''Flat''' No caps are drawn, and the stroke has flat ends. * '''Triangle''' Triangular caps are drawn. The distance from each endpoint to the tip of the triangle is half the stroke's thickness. * '''Square''' Square caps are drawn. These extend the stroke by half its thickness at each end. * '''Round''' Circular caps are drawn. The radius is half the stroke's thickness.}} |- {{Setting|'''Draw&nbsp;dashed&nbsp;stroke'''|Determines whether the stroke is drawn with dashing. If dashing is enabled, then each dash has the cap style specified by '''Stroke caps'''.}} |- {{Setting|'''Dash&nbsp;length'''|Specifies the length of each visible dash, in pixels.}} |- {{Setting|'''Gap&nbsp;length'''|Specifies the length of the empty gap between dashes, in pixels.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/StrokeWidget.html StrokeWidget]</code> class [[Category:Interface]] 62b9e654b32a089532ec45469e46f114cda2df31 Table Widget 0 512 517 2023-07-15T12:50:06Z Eric Lengyel 1 Created page with "The '''Table Widget''' displays a table with a fixed number of columns in a box with a scroll bar. The widget color controls the color of the table's border. == Settings == The following settings are available specifically for Table Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Table&nbsp;Settings'''}} |- {{Setting|'''Number of columns'''|Specifies the number of columns in the table.}} |- {{Setting|'''Cell size X'''|Specifies the hori..." wikitext text/x-wiki The '''Table Widget''' displays a table with a fixed number of columns in a box with a scroll bar. The widget color controls the color of the table's border. == Settings == The following settings are available specifically for Table Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Table&nbsp;Settings'''}} |- {{Setting|'''Number of columns'''|Specifies the number of columns in the table.}} |- {{Setting|'''Cell size X'''|Specifies the horizontal size of each cell in the table. The width of the widget should be a multiple of this value plus 16 pixels for the scroll bar.}} |- {{Setting|'''Cell size Y'''|Specifies the vertical size of each cell in the table. The height of the widget should be a multiple of this value to avoid extra space at the bottom of the table.}} |- {{Setting|'''Item offset X'''|Specifies a horizontal offset for items displayed in the table.}} |- {{Setting|'''Item offset Y'''|Specifies a vertical offset for items displayed in the table.}} |- {{Setting|'''Highlight inset X'''|Specifies the left and right inset for the highlight box rendered behind selected items in the table.}} |- {{Setting|'''Highlight inset Y'''|Specifies the top and bottom inset for the highlight box rendered behind selected items in the table.}} |- {{Setting|'''Allow multiple selection'''|Enables multiple items to be selected in the table at the same time.}} |- {{Setting|'''Render focus plain (no glow)'''|Causes the keyboard focus glow to not be rendered.}} |- {{Setting|'''Leave table items enabled'''|Causes items in the table to be left in an enabled state to allow user interaction directly with each item.}} |- {{Setting|'''Background color'''|Specifies the color of the table background.}} |- {{Setting|'''Highlight color'''|If checked, specifies the color of the highlight used to indicate selected items, overriding the default highlight color specified by the <code>$hiliteColor</code> system variable.}} |- {{Setting|'''Focus glow color'''|If checked, specifies the color of the glow drawn around the table when it has the keyboard focus, overriding the default glow color given by the <code>$hiliteColor</code> system variable multiplied by 5/8.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/TableWidget.html TableWidget]</code> class [[Category:Interface]] d53279e6e8b7725968a8d230439daa586b4f001a Text Widget 0 513 518 2023-07-15T12:51:08Z Eric Lengyel 1 Created page with "The '''Text Widget''' displays a text string using the rendering technology in the [[Slug Library]]. Other widgets that display text, such as a check box, are derived from the Text Widget and possess all of the same capabilities. In the [[Panel Editor]], the text string box contains the string that is displayed by the widget. If the text is displayed as multiple lines (because '''Box mode''' is set to '''Wrap text'''), then a hard line break can be inserted by entering..." wikitext text/x-wiki The '''Text Widget''' displays a text string using the rendering technology in the [[Slug Library]]. Other widgets that display text, such as a check box, are derived from the Text Widget and possess all of the same capabilities. In the [[Panel Editor]], the text string box contains the string that is displayed by the widget. If the text is displayed as multiple lines (because '''Box mode''' is set to '''Wrap text'''), then a hard line break can be inserted by entering <code>\n</code> in the text string. Formatting directives may also be embedded inside the text string. See [[Text Formatting]] for details. The '''Widget color''' setting controls the color of the text. == Settings == The following settings are available specifically for Text Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Text&nbsp;Settings'''}} |- {{Setting|'''Font'''|Determines in what font the text is displayed.}} |- {{Setting|'''Font&nbsp;size'''|Specifies the size of the font. This corresponds to the height of the em square for the font, in pixels. The heights of capital letters in a font are typically about 70% of this size, but this can vary significantly from one font to another.}} |- {{Setting|'''Stretch&nbsp;factor'''|Specifies a stretch factor applied to the font only in the horizontal direction. This is a scale applied to each glyph as well as the advance width, tracking, and kerning distances. Set to 1.0 for no stretch.}} |- {{Setting|'''Alignment'''|Determines the alignment of the text within the widget's bounding box. This can be '''Left''', '''Center''', or '''Right'''.}} |- {{Setting|'''Box&nbsp;mode'''|Determines what action is taken when the text does not fit within the horizontal bounds of the widget. If this is set to '''Clip text''', then text that flows beyond the left or right edge of the widget's bounding box is clipped. If this is set to '''Wrap text''', then the text is displayed as multiple lines that are broken after spaces or hyphens. If this set to '''Overflow''', then text that flows beyond the left or right edge is rendered outside the bounding box without clipping.}} |- {{HeadingSetting|'''Layout&nbsp;Settings'''}} |- {{Setting|'''Leading (em)'''|Specifies the vertical distance between two consecutive baselines in multi-line text, in em units. The default value of 1.2&#x202F;em produces a typical line spacing.}} |- {{Setting|'''Tracking (em)'''|Specifies additional horizontal space that is inserted between all characters, in em units.}} |- {{Setting|'''Skew ratio (x/y)'''|Specifies a skew setting that causes slanted text to be rendered. This is the ratio of the change in ''x'' coordinate to the change in ''y'' coordinate, where the ''y'' coordinate is measured upward from the baseline. Positive skews cause text to be slanted to the right, and negative skews cause text to be slanted to the left.}} |- {{Setting|'''Enable&nbsp;glyph&nbsp;kerning'''|Determines whether kerning is applied to the text. When this is enabled, information taken from tables in the original font are used to adjust the spacing between certain pairs of characters to improve visual appearance.}} |- {{Setting|'''Enable&nbsp;combining&nbsp;marks'''|Determines whether Unicode combining marks are positioned upon the preceding base character using information contained in the original font.}} |- {{Setting|'''Enable&nbsp;sequence&nbsp;replacement'''|Determines whether sequence replacement is generally applied to the text. The specific types of sequence replacements are individually enabled by the Sequence Replacement Settings below.}} |- {{Setting|'''Enable&nbsp;alternate&nbsp;glyphs'''|Determines whether alternate substitution is generally applied to the text. The specific types of alternate substitutions are individually enabled by the Alternate Substitution Settings below.}} |- {{Setting|'''Enable&nbsp;color&nbsp;layers'''|Determines whether glyphs like emoji are rendered with multiple color layers when available in the font. If this is not checked, then monochrome glyphs are always rendered.}} |- {{Setting|'''Apply&nbsp;text&nbsp;color&nbsp;to&nbsp;layers'''|Determines whether the colors of multiple layers are multiplied by the widget color.}} |- {{Setting|'''Draw&nbsp;underline'''|Specifies whether the underline decoration is drawn underneath the text.}} |- {{Setting|'''Draw&nbsp;strikethrough'''|Specifies whether the strikethrough decoration is drawn through the text.}} |- {{Setting|'''Use&nbsp;format&nbsp;directives'''|Determines whether embedded formatting directives are applied in the text. See [[Text Formatting]] for information about format directives.}} |- {{Setting|'''Primary&nbsp;layout&nbsp;right-to-left'''|Indicates that the primary writing direction is right-to-left.}} |- {{Setting|'''Enable&nbsp;bidirectional&nbsp;layout'''|Determines whether bidirectional text layout is enabled.}} |- {{Setting|'''Enable&nbsp;grid&nbsp;positioning'''|Determines whether the grid positioning is enabled. When this is turned on, each glyph is horizontally centered on its drawing position, and the distance from one glyph to the next is always the tracking distance.}} |- {{HeadingSetting|'''Paragraph&nbsp;Settings'''}} |- {{Setting|'''Enable&nbsp;full&nbsp;justification'''|Determines whether full justification is enabled. If this is checked, then space characters are stretched as necessary so that text is aligned with both the left and right sides of the bounding box.}} |- {{Setting|'''Enable&nbsp;paragraph&nbsp;attributes'''|Determines whether paragraph spacing, margins, and indent attributes are enabled. '''Box mode''' must also be set to '''Wrap text''' for paragraph attributes to apply.}} |- {{Setting|'''Paragraph&nbsp;spacing'''|Specifies the spacing between paragraphs, in em units.}} |- {{Setting|'''Paragraph&nbsp;left&nbsp;margin'''|Specifies the size of the left margin, in pixels.}} |- {{Setting|'''Paragraph&nbsp;right&nbsp;margin'''|Specifies the size of the right margin, in pixels.}} |- {{Setting|'''Paragraph&nbsp;first-line&nbsp;indent'''|Specifies the size of the indent for the first line of a paragraph, in pixels.}} |- {{HeadingSetting|'''Font&nbsp;Rendering&nbsp;Settings'''}} |- {{Setting|'''Render&nbsp;with&nbsp;optical&nbsp;weight'''|Specifies that the coverage values calculated on the boundaries of a glyph are to be increased to make the glyphs appear heavier. This is useful for improving readability at small font sizes.}} |- {{Setting|'''Render&nbsp;adaptive&nbsp;supersampling'''|Specifies whether glyphs are rendered with adaptive supersampling for high quality at small font sizes.}} |- {{Setting|'''Use&nbsp;bounding&nbsp;polygons'''|Specifies whether the bounding polygon optimization is enabled for rendered glyphs. This setting reduces the number of pixels covered by each glyph by using a tight polygon with 3&ndash;6 sides instead of a quad to render each one. This has no effect on the visual appearance of the text, but it can increase performance for text rendered at large sizes. This can have a ''negative'' effect on performance when text is rendered at small sizes, so it should not be enabled in those cases.}} |- {{Setting|'''Use&nbsp;rectangle&nbsp;optimization'''|Specifies that glyphs are to be rendered as rectangle primitives, if supported by the hardware. This optimization should be enabled only for text that is known to always be rendered aligned to the screen axes.}} |- {{Setting|'''Enable&nbsp;color&nbsp;gradient'''|Specifies that a gradient is applied to the glyph instead of a constant color. The following settings control the appearance of the gradient.}} |- {{Setting|'''Secondary&nbsp;text&nbsp;color'''|Specifies the secondary color used when the color gradient setting is enabled.}} |- {{Setting|'''Primary&nbsp;gradient&nbsp;Y&nbsp;(em)'''|Specifies the distance above the baseline, in em units, at which the primary text color occurs in the gradient.}} |- {{Setting|'''Secondary&nbsp;gradient&nbsp;Y&nbsp;(em)'''|Specifies the distance above the baseline, in em units, at which the secondary text color occurs in the gradient.}} |- {{HeadingSetting|'''Glyph&nbsp;Effect&nbsp;Settings'''}} |- {{Setting|'''Glyph&nbsp;effect&nbsp;type'''|Determines what special effect is applied to the text. If this is set to '''None''', then no effect is applied, and the following glyph effect parameters are ignored. If this is set to '''Shadow''', then a hard drop shadow is rendered behind the text. If this is set to '''Outline''', then an outline effect is rendered behind the text. The font must have been imported with outline glyph generation enabled for the outline effect to appear.}} |- {{Setting|'''Glyph&nbsp;effect&nbsp;offset&nbsp;X&nbsp;(em)'''|Specifies the offset of the glyph effect in the <i>x</i> direction, in em units.}} |- {{Setting|'''Glyph&nbsp;effect&nbsp;offset&nbsp;Y&nbsp;(em)'''|Specifies the offset of the glyph effect in the <i>y</i> direction, in em units.}} |- {{Setting|'''Glyph&nbsp;effect&nbsp;color'''|Specifies the color of the glyph effect.}} |- {{HeadingSetting|'''Sequence&nbsp;Replacement&nbsp;Settings'''}} |- {{Setting|'''Glyph&nbsp;composition'''|If sequence replacement is enabled, determines whether glyph composition is applied to the text. This allows the use of skin tone modifiers, family emoticons, and national flags when these are included in a font.}} |- {{Setting|'''Standard&nbsp;ligatures'''|If sequence replacement is enabled, determines whether standard ligatures are rendered in place of certain character sequences. Standard ligatures typically include things like the single glyph "&#xFB01;" being rendered in place of the two letters "f" and "i", but some fonts consider these to be discretionary.}} |- {{Setting|'''Required&nbsp;ligatures'''|If sequence replacement is enabled, determines whether ligatures required by certain writing systems are rendered in place of certain character sequences.}} |- {{Setting|'''Discretionary&nbsp;ligatures'''|If sequence replacement is enabled, determines whether discretionary ligatures are rendered in place of certain character sequences. This is disabled by default.}} |- {{Setting|'''Historical&nbsp;ligatures'''|If sequence replacement is enabled, determines whether historical ligatures are rendered in place of certain character sequences. This is disabled by default.}} |- {{Setting|'''Alternative&nbsp;fractions'''|If sequence replacement is enabled, determines whether alternative fractions, usually numerator and denominator stacked vertically with a horizontal line separating them, are rendered in place of fractions that would ordinarily be rendered with a diagonal slash. This is disabled by default. If enabled, this option has an effect only if alternative fractions are provided by the font.}} |- {{HeadingSetting|'''Alternate&nbsp;Substitution&nbsp;Settings'''}} |- {{Setting|'''Stylistic&nbsp;set'''|If alternate substitution is enabled, determines the index of the stylistic set to apply to the text. Most fonts define a small number of sets, if any at all, and they often affect only a small number of characters.}} |- {{Setting|'''Historical&nbsp;alternates'''|If alternate substitution is enabled, determines whether historical alternates are substituted in the text.}} |- {{Setting|'''Lowercase&nbsp;small&nbsp;caps'''|If alternate substitution is enabled, determines whether lowercase letters are replaced by small caps variants. This may also affect additional glyphs that are not letters, depending on the font.}} |- {{Setting|'''Uppercase&nbsp;small&nbsp;caps'''|If alternate substitution is enabled, determines whether uppercase letters are replaced by small caps variants. This may also affect additional glyphs that are not letters, depending on the font.}} |- {{Setting|'''Titling&nbsp;caps'''|If alternate substitution is enabled, determines whether uppercase letters are replaced by titling caps variants. This may also affect additional glyphs that are not letters, depending on the font.}} |- {{Setting|'''Unicase&nbsp;forms'''|If alternate substitution is enabled, determines whether unicase forms are substituted in the text, if available in the font.}} |- {{Setting|'''Case-sensitive&nbsp;forms'''|If alternate substitution is enabled, determines whether case-sensitive forms are substituted in the text. This generally applies to punctuation that shifts or changes size when used with capital letters.}} |- {{Setting|'''Slashed&nbsp;zero'''|If alternate substitution is enabled, determines whether slashed zero is substituted for ordinary zero in the text.}} |- {{Setting|'''Fractions'''|If alternate substitution is enabled, determines whether numerators, denominators, and the fraction slash are substituted for sequences containing numbers followed by a slash followed by more numbers.}} |- {{Setting|'''Hyphen&nbsp;minus'''|If alternate substitution is enabled, determines whether hyphens are replaced by minus signs.}} |- {{Setting|'''Figure&nbsp;style'''|If alternate substitution is enabled, determines whether numerical figures are replaced with alternates of a different style. Fonts may define lining figures and oldstyle figures, and the default may be either variant.}} |- {{Setting|'''Figure&nbsp;spacing'''|If alternate substitution is enabled, determines whether numerical figures are replaced with alternates with different spacing. Fonts may define tabular figures and proportional figures, and the default may be either variant.}} |- {{Setting|'''Subscript/superscript'''|If alternate substitution is enabled, determines whether subscript or superscript alternates are substituted in the text. Fonts may define subscripts, superscripts, scientific inferiors, and ordinals. The ranges of characters affected by these alternates varies by font.}} |} == See Also == * [[Widgets]] * [[Text Formatting]] * [[Font Importer]] * <code>[http://c4engine.com/docs/InterfaceMgr/TextWidget.html TextWidget]</code> class [[Category:Interface]] 83642e09ce4d9ba2f168027cdd7768370f1c9b69 Slug 0 442 519 445 2023-07-15T12:51:29Z Eric Lengyel 1 Redirected page to [[Slug Library]] wikitext text/x-wiki #REDIRECT [[Slug Library]] d79b17d8a4ef7dcef1fd35c28ac93c666ed99d06 Slug Library 0 514 520 2023-07-15T12:51:33Z Eric Lengyel 1 Created page with "__NOTOC__ [[File:Slug.png|right]] The Slug Library is a product developed by Terathon Software for rendering high-quality, resolution-independent text and vector graphics in 3D applications on the GPU. It is used to render all text and icons in the C4 Engine. Detailed information can be found on the [http://sluglibrary.com/ Slug website]. == See Also == * [[Text Widget]] * [[Slug Effects]]" wikitext text/x-wiki __NOTOC__ [[File:Slug.png|right]] The Slug Library is a product developed by Terathon Software for rendering high-quality, resolution-independent text and vector graphics in 3D applications on the GPU. It is used to render all text and icons in the C4 Engine. Detailed information can be found on the [http://sluglibrary.com/ Slug website]. == See Also == * [[Text Widget]] * [[Slug Effects]] 59d5739b7087c94b7faf9d61616bd3c14b28496e Text Button Widget 0 515 521 2023-07-15T12:52:31Z Eric Lengyel 1 Created page with "The '''Text Button Widget''' displays a clickable text string. The widget color controls the color of the text. == Settings == The following settings are available specifically for Text Button Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Text&nbsp;Button&nbsp;Settings'''}} |- {{Setting|'''Highlight color'''|Determines the color in which the text is rendered while the mouse button is pressed inside the text.}} |} == See Also == * ..." wikitext text/x-wiki The '''Text Button Widget''' displays a clickable text string. The widget color controls the color of the text. == Settings == The following settings are available specifically for Text Button Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Text&nbsp;Button&nbsp;Settings'''}} |- {{Setting|'''Highlight color'''|Determines the color in which the text is rendered while the mouse button is pressed inside the text.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/TextButtonWidget.html TextButtonWidget]</code> class [[Category:Interface]] 0db7a2ed3b114cde4021233420822f947c86f180 Tree Widget 0 516 522 2023-07-15T12:53:30Z Eric Lengyel 1 Created page with "The '''Tree Widget''' displays a list box with a scroll bar, and the items can have collapsable subtrees. The widget color controls the color of the tree's border. == Settings == The following settings are available specifically for Tree Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Tree&nbsp;Settings'''}} |- {{Setting|'''Item spacing'''|Specifies the vertical distance from one list item to the next. The height of the list box should..." wikitext text/x-wiki The '''Tree Widget''' displays a list box with a scroll bar, and the items can have collapsable subtrees. The widget color controls the color of the tree's border. == Settings == The following settings are available specifically for Tree Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''Tree&nbsp;Settings'''}} |- {{Setting|'''Item spacing'''|Specifies the vertical distance from one list item to the next. The height of the list box should be a multiple of this value to avoid extra space at the bottom of the list.}} |- {{Setting|'''Item offset X'''|Specifies a horizontal offset for items displayed in the list.}} |- {{Setting|'''Item offset Y'''|Specifies a vertical offset for items displayed in the list.}} |- {{Setting|'''Allow multiple selection'''|Enables multiple items to be selected in the list at the same time.}} |- {{Setting|'''Render focus plain (no glow)'''|Causes the keyboard focus glow to not be rendered.}} |- {{Setting|'''Leave list items enabled'''|Causes items in the list to be left in an enabled state to allow user interaction directly with the item.}} |- {{Setting|'''Background color'''|Specifies the color of the list background.}} |- {{Setting|'''Highlight color'''|If checked, specifies the color of the highlight used to indicate selected items, overriding the default highlight color specified by the <code>$hiliteColor</code> system variable.}} |- {{Setting|'''Focus glow color'''|If checked, specifies the color of the glow drawn around the list box when it has the keyboard focus, overriding the default glow color given by the <code>$hiliteColor</code> system variable multiplied by 5/8.}} |- {{Setting|'''Text item font'''|Determines what font is used to display plain text list items.}} |- {{Setting|'''Subitem indent spacing'''|Specifies by how much subitems are indented relative to their parent item.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/TreeWidget.html TreeWidget]</code> class [[Category:Interface]] 1aeb20440e58517a570ac5b9ba9d375eb918b428 World Viewport Widget 0 517 523 2023-07-15T12:53:56Z Eric Lengyel 1 Created page with "The '''World Viewport Widget''' renders a complete world inside a frustum viewport, and the it provides camera orbit functionality. The widget color is not used. == Settings == The following settings are available specifically for World Viewport Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''World&nbsp;Viewport&nbsp;Settings'''}} |- {{Setting|'''World clear color'''|If checked, specifies the clear color used to initialize the contents..." wikitext text/x-wiki The '''World Viewport Widget''' renders a complete world inside a frustum viewport, and the it provides camera orbit functionality. The widget color is not used. == Settings == The following settings are available specifically for World Viewport Widgets. {| {{Table}} {{Tablehead|Setting|Description}} |- {{HeadingSetting|'''World&nbsp;Viewport&nbsp;Settings'''}} |- {{Setting|'''World clear color'''|If checked, specifies the clear color used to initialize the contents of the viewport each time it is rendered.}} |} == See Also == * [[Widgets]] * <code>[http://c4engine.com/docs/InterfaceMgr/WorldViewportWidget.html WorldViewportWidget]</code> class [[Category:Interface]] 6f3080fa8bc33645ddc7b56f856948da1796e65a Foundations of Game Engine Development 0 518 524 2023-07-15T12:55:53Z Eric Lengyel 1 Created page with "''Foundations of Game Engine Development'', abbreviated FGED, is a series of books written by Eric Lengyel. It describes the mathematical and engineering details of many of the techniques used in the C4 Engine. More information is available on the [http://foundationsofgameenginedev.com/ FGED] website." wikitext text/x-wiki ''Foundations of Game Engine Development'', abbreviated FGED, is a series of books written by Eric Lengyel. It describes the mathematical and engineering details of many of the techniques used in the C4 Engine. More information is available on the [http://foundationsofgameenginedev.com/ FGED] website. ffa3baa0cc599f418adab324e26e4542c51f93bc FGED 0 519 525 2023-07-15T12:56:09Z Eric Lengyel 1 Redirected page to [[Foundations of Game Engine Development]] wikitext text/x-wiki #REDIRECT [[Foundations of Game Engine Development]] 65ddc6264c931c0e35d27c9c1551119a2893960b Screenshots 0 520 526 2023-07-15T12:58:08Z Eric Lengyel 1 Created page with "The C4 Engine can take screenshots and store them on the disk as TGA files. There are two different methods by which a screenshot can be taken, using the menu command in the [[C4 Menu]] or using the <code>shot</code> [[Command Console|console command]]. The console command can also be bound to an input control so that screenshots can be taken at the press of a button while playing a game. Screenshots are always stored in the user's documents directory in the C4 Engine s..." wikitext text/x-wiki The C4 Engine can take screenshots and store them on the disk as TGA files. There are two different methods by which a screenshot can be taken, using the menu command in the [[C4 Menu]] or using the <code>shot</code> [[Command Console|console command]]. The console command can also be bound to an input control so that screenshots can be taken at the press of a button while playing a game. Screenshots are always stored in the user's documents directory in the C4 Engine subfolder. == Menu Command == If the strip is visible at the bottom of the screen, then the Take Screenshot command in the [[C4 Menu]] can be used to take a screenshot. The shortcut Ctrl-\ can also be used when any interface window, such as the main menu or command console, is visible. When a screenshot is taken with this method, the name of the file is <code>C4_shot_xxxx.tga</code>, where <code>xxxx</code> is replaced by a number that starts at 1 and gets incremented every time a screenshot is taken. == Console Command == The <code>shot</code>&nbsp;''name'' command takes a screenshot and saves it as ''name''<code>.tga</code>. If a <code>#</code> character appears in the name, then the name from that point on is replaced with a screenshot count that starts at 1 and gets incremented each time it is used in a screenshot name. 802cff38f6c15f56f0c88c4cd0b01df0af8bfcc9 Simple Games 0 196 527 198 2023-09-12T21:29:53Z Eric Lengyel 1 wikitext text/x-wiki __NOTOC__ The C4 Engine ships with two basic game projects called <code>SimpleBall</code> and <code>SimpleChar</code>. Both are made up of two files that are heavily commented and represent nearly the minimum amount of code that needs to be written to have a working game module. You can tell the engine to load one of these game module by editing the file <code>Data/Engine/game.cfg</code> and changing the value of the variable <code>gameModuleName</code> to either <code>"SimpleBall"</code> or <code>"SimpleChar"</code>. To return to the large demo game, change <code>gameModuleName</code> back to <code>"The31st"</code>. == SimpleBall == [[File:Simpleball.jpg|right|frame|'''Figure 1.''' The SimpleBall game shows a room with dozens of glowing balls bouncing around.]] The '''SimpleBall''' game demonstrates a basic rigid body controller and particle system implementation. It also has controls for moving a spectator camera and registering a model type, controller type, and locator type. When the SimpleBall module starts, it displays a small dialog box. Click the '''Start''' button to load a world that demonstrates the basic functionality implemented in the game. The "SimpleBall" world contains dozens of yellow bouncing balls in a room, as shown in Figure 1, and every ball can collide with the environment or any other ball. The motion of the balls is controlled by the physics system, and the SimpleBall code responds to collisions by generating some sparks as a small particle system. * [[SimpleBall Source Code]] == SimpleChar == The '''SimpleChar''' game demonstrates a basic character controller and third-person chase camera. The character is able to perform basic interactions with the environment. To load a level after starting SimpleChar, you'll need to open the [[Command Console]] with the tilde key then use the <code>load</code> command. For example, type load <code>world/Teleport</code> to load the <code>Tutorials/world/Teleport.wld</code> world.) The SimpleChar tutorial does not have any user interface, and the gray screen shown at start-up is normal. To quit this game, use one of the methods described in [[Quick Tour]]. When the SimpleChar module is running, you will be able to run the soldier model around the world using the WSAD keys and the mouse. If the movement keys don't seem to work, make sure the strip at the bottom of the screen is not visible by pressing the Escape key. If the character is close enough to an interactive object such as gate that can be opened or a level that can be pulled, pointing toward the object and clicking the mouse will activate the controller attached to it. Note that many of the physical objects in various worlds will not work as they do in the demo game because they use special controllers that are not defined in the SimpleChar game. It is not a bug if you can walk through a crate in SimpleChar when that crate could be broken by the axe in the demo game, for example. * [[SimpleChar Source Code]] [[Category:Tutorials]] 61e27696d911884c433e70c6bd67dcd16d8500ef Category:Sound 14 521 528 2023-09-12T21:30:57Z Eric Lengyel 1 Created blank page wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Command Console 0 101 529 103 2023-09-12T21:35:29Z Eric Lengyel 1 /* Defining New Commands */ wikitext text/x-wiki [[File:Console.png|480px|right]] The '''Command Console''' window can be opened at any time by pressing the tilde/grave key. (On some non-English keyboards, the key directly below the Escape key should be used.) The window displays a command line and an output buffer as shown in the image to the right. If the C4 Engine was built using the debug settings, the window displays "(Debug)" to the right of the build number. The console stores a small command history that can be accessed with the up and down arrow keys. __TOC__ <br clear="right" /> == Core Engine Commands == The following table describes some of the commands that are built into the engine. New commands can be added by an application or plugin module (see below). {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|<code>address</code>|Displays the IP address of the local machine. Must be in a network game.}} |- {{Tablerow|<code>bind</code> ''key'' <code>"</code>''command''<code>"</code>|Binds the key whose name is ''key'' to the command specified by ''command''. Whenever the bound key is pressed in gameplay mode, the specified command is executed.}} |- {{Tablerow|<code>body</code>|Toggles the display of bounding boxes for active rigid bodies.}} |- {{Tablerow|<code>cmd</code>|Displays a list of available console commands.}} |- {{Tablerow|<code>disconnect</code>|Disconnects from a multiplayer game.}} |- {{Tablerow|<code>dump</code>|Writes a list of all currently allocated memory blocks to the file <code>Memory.txt</code>. Leak detection must be turned on.}} |- {{Tablerow|<code>exec</code> ''path''|Executes the file <code>Data/*/''path''.cfg</code>.}} |- {{Tablerow|<code>gentex</code>|Opens the [[Texture Generation]] tool, which renders textures for light projections, environment maps, and impostor textures. (Can only be invoked while a game world is running.)}} |- {{Tablerow|<code>heap</code>|(Advanced) Displays memory heap totals in the console.}} |- {{Tablerow|<code>load</code> ''name''|Loads the world <code>''name''.wld</code> for gameplay.}} |- {{Tablerow|<code>lrgn</code>|(Advanced) Toggles the display of light regions.}} |- {{Tablerow|<code>net</code>|Opens the Network window, which displays various network statistics. (The Network window can also be opened by choosing '''C4 > Network Window'''.)}} |- {{Tablerow|<code>norm</code>|Toggles the display of normal vectors.}} |- {{Tablerow|<code>quit</code>|Quits the C4 Engine.}} |- {{Tablerow|<code>record</code> ''name''|Starts recording video and/or audio to files that can later be imported as a movie. See [[Recording Movies]] for more information.}} |- {{Tablerow|<code>resolve</code> ''hostname''|Resolves a host name to an IP address. Must be in a network game.}} |- {{Tablerow|<code>restore</code> ''name''|Restore the previously saved game <code>Save/''name''.sav</code>.}} |- {{Tablerow|<code>save</code> ''name''|Save the current game as <code>Save/''name''.sav</code>.}} |- {{Tablerow|<code>say</code> <code>"</code>''message''<code>"</code>|Sends a chat message to all players in the current multiplayer game.}} |- {{Tablerow|<code>shot</code> ''name''|Takes a [[Screenshots|screenshot]] and saves it as <code>''name''.tga</code> in the user's Documents directory in a subfolder named C4 Engine. If a <code>#</code> character appears in the name, then the name from that point on is replaced with a screenshot count that starts at 1 and gets incremented each time it is used in a screenshot name.}} |- {{Tablerow|<code>smap</code> ''type''|(Advanced) Opens the Shadow Map window for a particular light type. The value of ''type'' must be <code>inft</code>, <code>pont</code>, or <code>spot</code>.}} |- {{Tablerow|<code>spth</code>|(Advanced) Toggles the display of sound flow paths.}} |- {{Tablerow|<code>stat</code>|Opens the Stats window, which displays various engine statistics. (The Stats window can also be accessed by choosing '''C4 > Stats Window'''.)}} |- {{Tablerow|<code>tang</code>|Toggles the display of tangent vectors.}} |- {{Tablerow|<code>time</code>|Opens the Time window, which displays the frame rate in frames/s and ms/frame, the current load on the GPU and CPU, and a detailed breakdown of the time the engine spends on specific features such as shadows and post processing. (The Time window can also be opened by choosing '''C4 > Time Window'''.)}} |- {{Tablerow|<code>unbind</code> ''key''|Unbinds the key whose name is ''key''.}} |- {{Tablerow|<code>undef</code> ''name''|Undefines the variable ''name'', if the variable is not permanent.}} |- {{Tablerow|<code>unload</code>|Unloads the current gameplay world.}} |- {{Tablerow|<code>var</code>|Displays a list of currently defined system variables.}} |- {{Tablerow|<code>wire</code>|Toggles the display of the wireframe overlay.}} |} == Tool Commands == The following commands are defined by the standard tools that ship with the C4 Engine. Most of these commands have equivalent items in the [[C4 Menu]]. If the ''name'' parameter is omitted from any of these commands, then a file picker dialog will appear to let you select a file. {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|<code>ifont</code>|Opens the [[Font Importer]] tool. (This tool can also be opened by choosing '''C4 > Import Font'''.)}} |- {{Tablerow|<code>imovie</code>|Opens the [[Movie Importer]] tool. (Movies can also be imported by choosing '''C4 > Import Movie'''.)}} |- {{Tablerow|<code>isound</code> ''name''|Imports the sound file <code>''name''.wav</code>. See also [[Sound Importer]]. (Sounds can also be imported by choosing '''C4 > Import Sound'''.)}} |- {{Tablerow|<code>istring</code> ''name''|Imports the string table file <code>''name''.txt</code>. See also [[String Tables]]. (String tables can also be imported by choosing '''C4 > Import String Table'''.)}} |- {{Tablerow|<code>itexture</code> ''name''|Imports the texture file <code>''name''.tga</code>. See also [[Texture Importer]]. (Textures can also be imported by choosing '''C4 > Import Texture'''.)}} |- {{Tablerow|<code>model</code> ''name''|Opens the model file <code>''name''.mdl</code> in the [[Model Viewer]] tool. (Models can also be opened by choosing '''C4 > Open Model'''.)}} |- {{Tablerow|<code>movie</code> ''name''|Opens the movie file <code>''name''.mvi</code> in the [[Movie Player]] tool. (Movies can also be opened by choosing '''C4 > Open Movie'''.)}} |- {{Tablerow|<code>pack</code> ''name''|Creates a pack file, where ''name'' is the name of a top-level subfolder in the <code>Data</code> directory. See also [[Pack Files and Virtual Directories]].}} |- {{Tablerow|<code>panel</code> ''name''|Opens the panel file <code>''name''.pan</code> in the [[Panel Editor]] tool. (Panels can also be opened by choosing '''C4 > Open Panel'''.)}} |- {{Tablerow|<code>sound</code> ''name''|Opens the sounds file <code>''name''.snd</code> in the [[Sound Player]] tool. (Sounds can also be opened by choosing '''C4 > Open Sound'''.)}} |- {{Tablerow|<code>texture</code> ''name''|Opens the texture file <code>''name''.tex</code> in the [[Texture Viewer]] tool. (Textures can also be opened by choosing '''C4 > Open Texture'''.)}} |- {{Tablerow|<code>world</code> ''name''|Opens the world file <code>''name''.wld</code> in the [[World Editor]] tool. (Worlds can also be opened by choosing '''C4 > Open World'''.)}} |} == Defining New Commands == Application modules and plugin modules can add their own commands to the engine by creating new instances of the <code>Command</code> class. The constructor for the <code>Command</code> class takes a command string and a pointer to an observer object that is invoked when the command is executed. For example, to define a command called explode that causes the <code>MyClass::ExplodeFunction()</code> function to be called, you would construct a new <code>Command</code> instance as follows. <syntaxhighlight lang="c++"> CommandObserver<MyClass> explodeObserver(this, &MyClass::ExplodeFunction); Command *explodeCommand = new Command("explode", &explodeObserver); </syntaxhighlight> Once the command has been constructed, it needs to be added to the engine's command list before it will be recognized. This is done by calling the <code>Engine::AddCommand()</code> function. Continuing the explode example, you would make the following call to add the explode command to the engine. <syntaxhighlight lang="c++"> TheEngine->AddCommand(explodeCommand); </syntaxhighlight> Destroying the <code>Command</code> instance automatically removes the command from the engine. The observer event handling function assigned to a new command must have the following prototype. <syntaxhighlight lang="c++"> void ExplodeFunction(Command *command, const char *text); </syntaxhighlight> When a command is entered into the console (or executed from a file), the observer event handler is invoked, and the text passed in through the text parameter provides the rest of the command line. For instance, the command <code>explode 1 boom</code> would cause the <code>ExplodeFunction()</code> function to be called with a pointer to the string <code>"1 boom"</code>. == Console Output == You can write text to the Command Console window by calling the <code>Engine::Report()</code> function. The string passed to the <code>Engine::Report()</code> function is output to the console whenever the <code>flags</code> parameter does not include the bit <code>kReportLog</code>. For example, to write some integer value to the console with a text label, you could make the following call: <source lang="c++"> Engine::Report(String<63>("My value is now ") += myValue); </source> (The number 63 represents the maximum length of the string stored in the <code>String</code> object. This number can be omitted altogether to get an arbitrarily large string, but it causes extra memory allocations.) == Disabling the Console == The Command Console window can be opened when the keyboard is in either interface mode or game input mode, and both of these methods must be disabled in order to prevent access to the console. To make the Command Console window completely inaccessible, make the following two function calls: <source lang="c++"> TheInputMgr->SetConsoleCallback(nullptr); TheInterfaceMgr->DisableConsole(); </source> If the Command Console window is later going to be enabled again, then it will also be necessary to save the previous console procedure so that it can be restored. This can be done by expanding the above code as follows: <source lang="c++"> // Declared in some larger scope: InputMgr::KeyCallback savedConsoleCallback; void *savedConsoleCookie; ... savedConsoleCallback = TheInputMgr->GetConsoleCallback(); savedConsoleCookie = TheInputMgr->GetConsoleCookie(); TheInputMgr->SetConsoleCallback(nullptr); TheInterfaceMgr->DisableConsole(); </source> To enable the Command Console window again and restore the previous console procedure in the Input Manager, use the following code: <source lang="c++"> TheInputMgr->SetConsoleProc(savedConsoleProc, savedConsoleCookie); TheInterfaceMgr->EnableConsole(); </source> == See Also == * [[C4 Menu]] * [[List of System Variables]] a8faa26d7c73c345c3317a278df5723b7dfc9ccb 530 529 2023-09-12T21:35:39Z Eric Lengyel 1 /* Console Output */ wikitext text/x-wiki [[File:Console.png|480px|right]] The '''Command Console''' window can be opened at any time by pressing the tilde/grave key. (On some non-English keyboards, the key directly below the Escape key should be used.) The window displays a command line and an output buffer as shown in the image to the right. If the C4 Engine was built using the debug settings, the window displays "(Debug)" to the right of the build number. The console stores a small command history that can be accessed with the up and down arrow keys. __TOC__ <br clear="right" /> == Core Engine Commands == The following table describes some of the commands that are built into the engine. New commands can be added by an application or plugin module (see below). {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|<code>address</code>|Displays the IP address of the local machine. Must be in a network game.}} |- {{Tablerow|<code>bind</code> ''key'' <code>"</code>''command''<code>"</code>|Binds the key whose name is ''key'' to the command specified by ''command''. Whenever the bound key is pressed in gameplay mode, the specified command is executed.}} |- {{Tablerow|<code>body</code>|Toggles the display of bounding boxes for active rigid bodies.}} |- {{Tablerow|<code>cmd</code>|Displays a list of available console commands.}} |- {{Tablerow|<code>disconnect</code>|Disconnects from a multiplayer game.}} |- {{Tablerow|<code>dump</code>|Writes a list of all currently allocated memory blocks to the file <code>Memory.txt</code>. Leak detection must be turned on.}} |- {{Tablerow|<code>exec</code> ''path''|Executes the file <code>Data/*/''path''.cfg</code>.}} |- {{Tablerow|<code>gentex</code>|Opens the [[Texture Generation]] tool, which renders textures for light projections, environment maps, and impostor textures. (Can only be invoked while a game world is running.)}} |- {{Tablerow|<code>heap</code>|(Advanced) Displays memory heap totals in the console.}} |- {{Tablerow|<code>load</code> ''name''|Loads the world <code>''name''.wld</code> for gameplay.}} |- {{Tablerow|<code>lrgn</code>|(Advanced) Toggles the display of light regions.}} |- {{Tablerow|<code>net</code>|Opens the Network window, which displays various network statistics. (The Network window can also be opened by choosing '''C4 > Network Window'''.)}} |- {{Tablerow|<code>norm</code>|Toggles the display of normal vectors.}} |- {{Tablerow|<code>quit</code>|Quits the C4 Engine.}} |- {{Tablerow|<code>record</code> ''name''|Starts recording video and/or audio to files that can later be imported as a movie. See [[Recording Movies]] for more information.}} |- {{Tablerow|<code>resolve</code> ''hostname''|Resolves a host name to an IP address. Must be in a network game.}} |- {{Tablerow|<code>restore</code> ''name''|Restore the previously saved game <code>Save/''name''.sav</code>.}} |- {{Tablerow|<code>save</code> ''name''|Save the current game as <code>Save/''name''.sav</code>.}} |- {{Tablerow|<code>say</code> <code>"</code>''message''<code>"</code>|Sends a chat message to all players in the current multiplayer game.}} |- {{Tablerow|<code>shot</code> ''name''|Takes a [[Screenshots|screenshot]] and saves it as <code>''name''.tga</code> in the user's Documents directory in a subfolder named C4 Engine. If a <code>#</code> character appears in the name, then the name from that point on is replaced with a screenshot count that starts at 1 and gets incremented each time it is used in a screenshot name.}} |- {{Tablerow|<code>smap</code> ''type''|(Advanced) Opens the Shadow Map window for a particular light type. The value of ''type'' must be <code>inft</code>, <code>pont</code>, or <code>spot</code>.}} |- {{Tablerow|<code>spth</code>|(Advanced) Toggles the display of sound flow paths.}} |- {{Tablerow|<code>stat</code>|Opens the Stats window, which displays various engine statistics. (The Stats window can also be accessed by choosing '''C4 > Stats Window'''.)}} |- {{Tablerow|<code>tang</code>|Toggles the display of tangent vectors.}} |- {{Tablerow|<code>time</code>|Opens the Time window, which displays the frame rate in frames/s and ms/frame, the current load on the GPU and CPU, and a detailed breakdown of the time the engine spends on specific features such as shadows and post processing. (The Time window can also be opened by choosing '''C4 > Time Window'''.)}} |- {{Tablerow|<code>unbind</code> ''key''|Unbinds the key whose name is ''key''.}} |- {{Tablerow|<code>undef</code> ''name''|Undefines the variable ''name'', if the variable is not permanent.}} |- {{Tablerow|<code>unload</code>|Unloads the current gameplay world.}} |- {{Tablerow|<code>var</code>|Displays a list of currently defined system variables.}} |- {{Tablerow|<code>wire</code>|Toggles the display of the wireframe overlay.}} |} == Tool Commands == The following commands are defined by the standard tools that ship with the C4 Engine. Most of these commands have equivalent items in the [[C4 Menu]]. If the ''name'' parameter is omitted from any of these commands, then a file picker dialog will appear to let you select a file. {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|<code>ifont</code>|Opens the [[Font Importer]] tool. (This tool can also be opened by choosing '''C4 > Import Font'''.)}} |- {{Tablerow|<code>imovie</code>|Opens the [[Movie Importer]] tool. (Movies can also be imported by choosing '''C4 > Import Movie'''.)}} |- {{Tablerow|<code>isound</code> ''name''|Imports the sound file <code>''name''.wav</code>. See also [[Sound Importer]]. (Sounds can also be imported by choosing '''C4 > Import Sound'''.)}} |- {{Tablerow|<code>istring</code> ''name''|Imports the string table file <code>''name''.txt</code>. See also [[String Tables]]. (String tables can also be imported by choosing '''C4 > Import String Table'''.)}} |- {{Tablerow|<code>itexture</code> ''name''|Imports the texture file <code>''name''.tga</code>. See also [[Texture Importer]]. (Textures can also be imported by choosing '''C4 > Import Texture'''.)}} |- {{Tablerow|<code>model</code> ''name''|Opens the model file <code>''name''.mdl</code> in the [[Model Viewer]] tool. (Models can also be opened by choosing '''C4 > Open Model'''.)}} |- {{Tablerow|<code>movie</code> ''name''|Opens the movie file <code>''name''.mvi</code> in the [[Movie Player]] tool. (Movies can also be opened by choosing '''C4 > Open Movie'''.)}} |- {{Tablerow|<code>pack</code> ''name''|Creates a pack file, where ''name'' is the name of a top-level subfolder in the <code>Data</code> directory. See also [[Pack Files and Virtual Directories]].}} |- {{Tablerow|<code>panel</code> ''name''|Opens the panel file <code>''name''.pan</code> in the [[Panel Editor]] tool. (Panels can also be opened by choosing '''C4 > Open Panel'''.)}} |- {{Tablerow|<code>sound</code> ''name''|Opens the sounds file <code>''name''.snd</code> in the [[Sound Player]] tool. (Sounds can also be opened by choosing '''C4 > Open Sound'''.)}} |- {{Tablerow|<code>texture</code> ''name''|Opens the texture file <code>''name''.tex</code> in the [[Texture Viewer]] tool. (Textures can also be opened by choosing '''C4 > Open Texture'''.)}} |- {{Tablerow|<code>world</code> ''name''|Opens the world file <code>''name''.wld</code> in the [[World Editor]] tool. (Worlds can also be opened by choosing '''C4 > Open World'''.)}} |} == Defining New Commands == Application modules and plugin modules can add their own commands to the engine by creating new instances of the <code>Command</code> class. The constructor for the <code>Command</code> class takes a command string and a pointer to an observer object that is invoked when the command is executed. For example, to define a command called explode that causes the <code>MyClass::ExplodeFunction()</code> function to be called, you would construct a new <code>Command</code> instance as follows. <syntaxhighlight lang="c++"> CommandObserver<MyClass> explodeObserver(this, &MyClass::ExplodeFunction); Command *explodeCommand = new Command("explode", &explodeObserver); </syntaxhighlight> Once the command has been constructed, it needs to be added to the engine's command list before it will be recognized. This is done by calling the <code>Engine::AddCommand()</code> function. Continuing the explode example, you would make the following call to add the explode command to the engine. <syntaxhighlight lang="c++"> TheEngine->AddCommand(explodeCommand); </syntaxhighlight> Destroying the <code>Command</code> instance automatically removes the command from the engine. The observer event handling function assigned to a new command must have the following prototype. <syntaxhighlight lang="c++"> void ExplodeFunction(Command *command, const char *text); </syntaxhighlight> When a command is entered into the console (or executed from a file), the observer event handler is invoked, and the text passed in through the text parameter provides the rest of the command line. For instance, the command <code>explode 1 boom</code> would cause the <code>ExplodeFunction()</code> function to be called with a pointer to the string <code>"1 boom"</code>. == Console Output == You can write text to the Command Console window by calling the <code>Engine::Report()</code> function. The string passed to the <code>Engine::Report()</code> function is output to the console whenever the <code>flags</code> parameter does not include the bit <code>kReportLog</code>. For example, to write some integer value to the console with a text label, you could make the following call: <syntaxhighlight lang="c++"> Engine::Report(String<63>("My value is now ") += myValue); </syntaxhighlight> (The number 63 represents the maximum length of the string stored in the <code>String</code> object. This number can be omitted altogether to get an arbitrarily large string, but it causes extra memory allocations.) == Disabling the Console == The Command Console window can be opened when the keyboard is in either interface mode or game input mode, and both of these methods must be disabled in order to prevent access to the console. To make the Command Console window completely inaccessible, make the following two function calls: <source lang="c++"> TheInputMgr->SetConsoleCallback(nullptr); TheInterfaceMgr->DisableConsole(); </source> If the Command Console window is later going to be enabled again, then it will also be necessary to save the previous console procedure so that it can be restored. This can be done by expanding the above code as follows: <source lang="c++"> // Declared in some larger scope: InputMgr::KeyCallback savedConsoleCallback; void *savedConsoleCookie; ... savedConsoleCallback = TheInputMgr->GetConsoleCallback(); savedConsoleCookie = TheInputMgr->GetConsoleCookie(); TheInputMgr->SetConsoleCallback(nullptr); TheInterfaceMgr->DisableConsole(); </source> To enable the Command Console window again and restore the previous console procedure in the Input Manager, use the following code: <source lang="c++"> TheInputMgr->SetConsoleProc(savedConsoleProc, savedConsoleCookie); TheInterfaceMgr->EnableConsole(); </source> == See Also == * [[C4 Menu]] * [[List of System Variables]] 383b1f1c6fb25ae25d81cdc27eaff493e67415e1 531 530 2023-09-12T21:35:51Z Eric Lengyel 1 /* Disabling the Console */ wikitext text/x-wiki [[File:Console.png|480px|right]] The '''Command Console''' window can be opened at any time by pressing the tilde/grave key. (On some non-English keyboards, the key directly below the Escape key should be used.) The window displays a command line and an output buffer as shown in the image to the right. If the C4 Engine was built using the debug settings, the window displays "(Debug)" to the right of the build number. The console stores a small command history that can be accessed with the up and down arrow keys. __TOC__ <br clear="right" /> == Core Engine Commands == The following table describes some of the commands that are built into the engine. New commands can be added by an application or plugin module (see below). {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|<code>address</code>|Displays the IP address of the local machine. Must be in a network game.}} |- {{Tablerow|<code>bind</code> ''key'' <code>"</code>''command''<code>"</code>|Binds the key whose name is ''key'' to the command specified by ''command''. Whenever the bound key is pressed in gameplay mode, the specified command is executed.}} |- {{Tablerow|<code>body</code>|Toggles the display of bounding boxes for active rigid bodies.}} |- {{Tablerow|<code>cmd</code>|Displays a list of available console commands.}} |- {{Tablerow|<code>disconnect</code>|Disconnects from a multiplayer game.}} |- {{Tablerow|<code>dump</code>|Writes a list of all currently allocated memory blocks to the file <code>Memory.txt</code>. Leak detection must be turned on.}} |- {{Tablerow|<code>exec</code> ''path''|Executes the file <code>Data/*/''path''.cfg</code>.}} |- {{Tablerow|<code>gentex</code>|Opens the [[Texture Generation]] tool, which renders textures for light projections, environment maps, and impostor textures. (Can only be invoked while a game world is running.)}} |- {{Tablerow|<code>heap</code>|(Advanced) Displays memory heap totals in the console.}} |- {{Tablerow|<code>load</code> ''name''|Loads the world <code>''name''.wld</code> for gameplay.}} |- {{Tablerow|<code>lrgn</code>|(Advanced) Toggles the display of light regions.}} |- {{Tablerow|<code>net</code>|Opens the Network window, which displays various network statistics. (The Network window can also be opened by choosing '''C4 > Network Window'''.)}} |- {{Tablerow|<code>norm</code>|Toggles the display of normal vectors.}} |- {{Tablerow|<code>quit</code>|Quits the C4 Engine.}} |- {{Tablerow|<code>record</code> ''name''|Starts recording video and/or audio to files that can later be imported as a movie. See [[Recording Movies]] for more information.}} |- {{Tablerow|<code>resolve</code> ''hostname''|Resolves a host name to an IP address. Must be in a network game.}} |- {{Tablerow|<code>restore</code> ''name''|Restore the previously saved game <code>Save/''name''.sav</code>.}} |- {{Tablerow|<code>save</code> ''name''|Save the current game as <code>Save/''name''.sav</code>.}} |- {{Tablerow|<code>say</code> <code>"</code>''message''<code>"</code>|Sends a chat message to all players in the current multiplayer game.}} |- {{Tablerow|<code>shot</code> ''name''|Takes a [[Screenshots|screenshot]] and saves it as <code>''name''.tga</code> in the user's Documents directory in a subfolder named C4 Engine. If a <code>#</code> character appears in the name, then the name from that point on is replaced with a screenshot count that starts at 1 and gets incremented each time it is used in a screenshot name.}} |- {{Tablerow|<code>smap</code> ''type''|(Advanced) Opens the Shadow Map window for a particular light type. The value of ''type'' must be <code>inft</code>, <code>pont</code>, or <code>spot</code>.}} |- {{Tablerow|<code>spth</code>|(Advanced) Toggles the display of sound flow paths.}} |- {{Tablerow|<code>stat</code>|Opens the Stats window, which displays various engine statistics. (The Stats window can also be accessed by choosing '''C4 > Stats Window'''.)}} |- {{Tablerow|<code>tang</code>|Toggles the display of tangent vectors.}} |- {{Tablerow|<code>time</code>|Opens the Time window, which displays the frame rate in frames/s and ms/frame, the current load on the GPU and CPU, and a detailed breakdown of the time the engine spends on specific features such as shadows and post processing. (The Time window can also be opened by choosing '''C4 > Time Window'''.)}} |- {{Tablerow|<code>unbind</code> ''key''|Unbinds the key whose name is ''key''.}} |- {{Tablerow|<code>undef</code> ''name''|Undefines the variable ''name'', if the variable is not permanent.}} |- {{Tablerow|<code>unload</code>|Unloads the current gameplay world.}} |- {{Tablerow|<code>var</code>|Displays a list of currently defined system variables.}} |- {{Tablerow|<code>wire</code>|Toggles the display of the wireframe overlay.}} |} == Tool Commands == The following commands are defined by the standard tools that ship with the C4 Engine. Most of these commands have equivalent items in the [[C4 Menu]]. If the ''name'' parameter is omitted from any of these commands, then a file picker dialog will appear to let you select a file. {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|<code>ifont</code>|Opens the [[Font Importer]] tool. (This tool can also be opened by choosing '''C4 > Import Font'''.)}} |- {{Tablerow|<code>imovie</code>|Opens the [[Movie Importer]] tool. (Movies can also be imported by choosing '''C4 > Import Movie'''.)}} |- {{Tablerow|<code>isound</code> ''name''|Imports the sound file <code>''name''.wav</code>. See also [[Sound Importer]]. (Sounds can also be imported by choosing '''C4 > Import Sound'''.)}} |- {{Tablerow|<code>istring</code> ''name''|Imports the string table file <code>''name''.txt</code>. See also [[String Tables]]. (String tables can also be imported by choosing '''C4 > Import String Table'''.)}} |- {{Tablerow|<code>itexture</code> ''name''|Imports the texture file <code>''name''.tga</code>. See also [[Texture Importer]]. (Textures can also be imported by choosing '''C4 > Import Texture'''.)}} |- {{Tablerow|<code>model</code> ''name''|Opens the model file <code>''name''.mdl</code> in the [[Model Viewer]] tool. (Models can also be opened by choosing '''C4 > Open Model'''.)}} |- {{Tablerow|<code>movie</code> ''name''|Opens the movie file <code>''name''.mvi</code> in the [[Movie Player]] tool. (Movies can also be opened by choosing '''C4 > Open Movie'''.)}} |- {{Tablerow|<code>pack</code> ''name''|Creates a pack file, where ''name'' is the name of a top-level subfolder in the <code>Data</code> directory. See also [[Pack Files and Virtual Directories]].}} |- {{Tablerow|<code>panel</code> ''name''|Opens the panel file <code>''name''.pan</code> in the [[Panel Editor]] tool. (Panels can also be opened by choosing '''C4 > Open Panel'''.)}} |- {{Tablerow|<code>sound</code> ''name''|Opens the sounds file <code>''name''.snd</code> in the [[Sound Player]] tool. (Sounds can also be opened by choosing '''C4 > Open Sound'''.)}} |- {{Tablerow|<code>texture</code> ''name''|Opens the texture file <code>''name''.tex</code> in the [[Texture Viewer]] tool. (Textures can also be opened by choosing '''C4 > Open Texture'''.)}} |- {{Tablerow|<code>world</code> ''name''|Opens the world file <code>''name''.wld</code> in the [[World Editor]] tool. (Worlds can also be opened by choosing '''C4 > Open World'''.)}} |} == Defining New Commands == Application modules and plugin modules can add their own commands to the engine by creating new instances of the <code>Command</code> class. The constructor for the <code>Command</code> class takes a command string and a pointer to an observer object that is invoked when the command is executed. For example, to define a command called explode that causes the <code>MyClass::ExplodeFunction()</code> function to be called, you would construct a new <code>Command</code> instance as follows. <syntaxhighlight lang="c++"> CommandObserver<MyClass> explodeObserver(this, &MyClass::ExplodeFunction); Command *explodeCommand = new Command("explode", &explodeObserver); </syntaxhighlight> Once the command has been constructed, it needs to be added to the engine's command list before it will be recognized. This is done by calling the <code>Engine::AddCommand()</code> function. Continuing the explode example, you would make the following call to add the explode command to the engine. <syntaxhighlight lang="c++"> TheEngine->AddCommand(explodeCommand); </syntaxhighlight> Destroying the <code>Command</code> instance automatically removes the command from the engine. The observer event handling function assigned to a new command must have the following prototype. <syntaxhighlight lang="c++"> void ExplodeFunction(Command *command, const char *text); </syntaxhighlight> When a command is entered into the console (or executed from a file), the observer event handler is invoked, and the text passed in through the text parameter provides the rest of the command line. For instance, the command <code>explode 1 boom</code> would cause the <code>ExplodeFunction()</code> function to be called with a pointer to the string <code>"1 boom"</code>. == Console Output == You can write text to the Command Console window by calling the <code>Engine::Report()</code> function. The string passed to the <code>Engine::Report()</code> function is output to the console whenever the <code>flags</code> parameter does not include the bit <code>kReportLog</code>. For example, to write some integer value to the console with a text label, you could make the following call: <syntaxhighlight lang="c++"> Engine::Report(String<63>("My value is now ") += myValue); </syntaxhighlight> (The number 63 represents the maximum length of the string stored in the <code>String</code> object. This number can be omitted altogether to get an arbitrarily large string, but it causes extra memory allocations.) == Disabling the Console == The Command Console window can be opened when the keyboard is in either interface mode or game input mode, and both of these methods must be disabled in order to prevent access to the console. To make the Command Console window completely inaccessible, make the following two function calls: <syntaxhighlight lang="c++"> TheInputMgr->SetConsoleCallback(nullptr); TheInterfaceMgr->DisableConsole(); </syntaxhighlight> If the Command Console window is later going to be enabled again, then it will also be necessary to save the previous console procedure so that it can be restored. This can be done by expanding the above code as follows: <syntaxhighlight lang="c++"> // Declared in some larger scope: InputMgr::KeyCallback savedConsoleCallback; void *savedConsoleCookie; ... savedConsoleCallback = TheInputMgr->GetConsoleCallback(); savedConsoleCookie = TheInputMgr->GetConsoleCookie(); TheInputMgr->SetConsoleCallback(nullptr); TheInterfaceMgr->DisableConsole(); </syntaxhighlight> To enable the Command Console window again and restore the previous console procedure in the Input Manager, use the following code: <syntaxhighlight lang="c++"> TheInputMgr->SetConsoleProc(savedConsoleProc, savedConsoleCookie); TheInterfaceMgr->EnableConsole(); </syntaxhighlight> == See Also == * [[C4 Menu]] * [[List of System Variables]] da6c468e624b4cef0e9261b4b1c279b2e2a30816 548 531 2024-11-27T09:11:12Z Eric Lengyel 1 /* Core Engine Commands */ wikitext text/x-wiki [[File:Console.png|480px|right]] The '''Command Console''' window can be opened at any time by pressing the tilde/grave key. (On some non-English keyboards, the key directly below the Escape key should be used.) The window displays a command line and an output buffer as shown in the image to the right. If the C4 Engine was built using the debug settings, the window displays "(Debug)" to the right of the build number. The console stores a small command history that can be accessed with the up and down arrow keys. __TOC__ <br clear="right" /> == Core Engine Commands == The following table describes some of the commands that are built into the engine. New commands can be added by an application or plugin module (see below). {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|<code>address</code>|Displays the IP address of the local machine. Must be in a network game.}} |- {{Tablerow|<code>bind</code> ''key'' <code>"</code>''command''<code>"</code>|Binds the key whose name is ''key'' to the command specified by ''command''. Whenever the bound key is pressed in gameplay mode, the specified command is executed.}} |- {{Tablerow|<code>body</code>|Toggles the display of bounding boxes for active rigid bodies.}} |- {{Tablerow|<code>cmd</code>|Displays a list of available console commands.}} |- {{Tablerow|<code>disconnect</code>|Disconnects from a multiplayer game.}} |- {{Tablerow|<code>dump</code>|Writes a list of all currently allocated memory blocks to the file <code>Memory.txt</code>. Leak detection must be turned on.}} |- {{Tablerow|<code>exec</code> ''path''|Executes the file <code>Data/*/''path''.cfg</code>.}} |- {{Tablerow|<code>gentex</code>|Opens the [[Texture Generation]] tool, which renders textures for light projections, environment maps, and impostor textures. (Can only be invoked while a game world is running.)}} |- {{Tablerow|<code>heap</code>|(Advanced) Displays memory heap totals in the console.}} |- {{Tablerow|<code>load</code> ''name''|Loads the world <code>''name''.wld</code> for gameplay.}} |- {{Tablerow|<code>lrgn</code>|(Advanced) Toggles the display of light regions.}} |- {{Tablerow|<code>net</code>|Opens the Network window, which displays various network statistics. (The Network window can also be opened by choosing '''C4 > Network Window'''.)}} |- {{Tablerow|<code>norm</code>|Toggles the display of normal vectors.}} |- {{Tablerow|<code>quit</code>|Quits the C4 Engine.}} |- {{Tablerow|<code>record</code> ''name''|Starts recording video and/or audio to files that can later be imported as a movie. See [[Recording Movies]] for more information.}} |- {{Tablerow|<code>resolve</code> ''hostname''|Resolves a host name to an IP address. Must be in a network game.}} |- {{Tablerow|<code>restore</code> ''name''|Restore the previously saved game <code>Save/''name''.sav</code>.}} |- {{Tablerow|<code>save</code> ''name''|Save the current game as <code>Save/''name''.sav</code>.}} |- {{Tablerow|<code>say</code> <code>"</code>''message''<code>"</code>|Sends a chat message to all players in the current multiplayer game.}} |- {{Tablerow|<code>shot</code> ''name''|Takes a [[Screenshots|screenshot]] and saves it as <code>''name''.tga</code> in the user's Documents directory in a subfolder named C4 Engine. If a <code>#</code> character appears in the name, then the name from that point on is replaced with a screenshot count that starts at 1 and gets incremented each time it is used in a screenshot name.}} |- {{Tablerow|<code>smap</code> ''type''|(Advanced) Opens the Shadow Map window for a particular light type. The value of ''type'' must be <code>inft</code>, <code>pont</code>, or <code>spot</code>.}} |- {{Tablerow|<code>spth</code>|(Advanced) Toggles the display of sound flow paths.}} |- {{Tablerow|<code>stat</code>|Opens the Stats window, which displays various engine statistics. (The Stats window can also be accessed by choosing '''C4 > Stats Window'''.)}} |- {{Tablerow|<code>tang</code>|Toggles the display of tangent vectors.}} |- {{Tablerow|<code>target</code> ''type''|(Advanced) Opens the Target window, which displays one of the offscreen render targets. The value of ''type'' can be one of the following: * <code>strc</code> &ndash; line depth in structure buffer * <code>grad</code> &ndash; gradient in structure buffer * <code>occl</code> &ndash; ambient occlusion buffer * <code>dist</code> &ndash; distortion buffer * <code>velo</code> &ndash; velocity buffer * <code>atms</code> &ndash; atmospheric shadowing buffer * <code>glbl</code> &ndash; glow/bloom buffer}} |- {{Tablerow|<code>time</code>|Opens the Time window, which displays the frame rate in frames/s and ms/frame, the current load on the GPU and CPU, and a detailed breakdown of the time the engine spends on specific features such as shadows and post processing. (The Time window can also be opened by choosing '''C4 > Time Window'''.)}} |- {{Tablerow|<code>tone</code>|(Advanced) Opens the Tone Mapping window, which displays a luminance histogram and tone mapping curve.}} |- {{Tablerow|<code>unbind</code> ''key''|Unbinds the key whose name is ''key''.}} |- {{Tablerow|<code>undef</code> ''name''|Undefines the variable ''name'', if the variable is not permanent.}} |- {{Tablerow|<code>unload</code>|Unloads the current gameplay world.}} |- {{Tablerow|<code>var</code>|Displays a list of currently defined system variables.}} |- {{Tablerow|<code>wire</code>|Toggles the display of the wireframe overlay.}} |} == Tool Commands == The following commands are defined by the standard tools that ship with the C4 Engine. Most of these commands have equivalent items in the [[C4 Menu]]. If the ''name'' parameter is omitted from any of these commands, then a file picker dialog will appear to let you select a file. {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|<code>ifont</code>|Opens the [[Font Importer]] tool. (This tool can also be opened by choosing '''C4 > Import Font'''.)}} |- {{Tablerow|<code>imovie</code>|Opens the [[Movie Importer]] tool. (Movies can also be imported by choosing '''C4 > Import Movie'''.)}} |- {{Tablerow|<code>isound</code> ''name''|Imports the sound file <code>''name''.wav</code>. See also [[Sound Importer]]. (Sounds can also be imported by choosing '''C4 > Import Sound'''.)}} |- {{Tablerow|<code>istring</code> ''name''|Imports the string table file <code>''name''.txt</code>. See also [[String Tables]]. (String tables can also be imported by choosing '''C4 > Import String Table'''.)}} |- {{Tablerow|<code>itexture</code> ''name''|Imports the texture file <code>''name''.tga</code>. See also [[Texture Importer]]. (Textures can also be imported by choosing '''C4 > Import Texture'''.)}} |- {{Tablerow|<code>model</code> ''name''|Opens the model file <code>''name''.mdl</code> in the [[Model Viewer]] tool. (Models can also be opened by choosing '''C4 > Open Model'''.)}} |- {{Tablerow|<code>movie</code> ''name''|Opens the movie file <code>''name''.mvi</code> in the [[Movie Player]] tool. (Movies can also be opened by choosing '''C4 > Open Movie'''.)}} |- {{Tablerow|<code>pack</code> ''name''|Creates a pack file, where ''name'' is the name of a top-level subfolder in the <code>Data</code> directory. See also [[Pack Files and Virtual Directories]].}} |- {{Tablerow|<code>panel</code> ''name''|Opens the panel file <code>''name''.pan</code> in the [[Panel Editor]] tool. (Panels can also be opened by choosing '''C4 > Open Panel'''.)}} |- {{Tablerow|<code>sound</code> ''name''|Opens the sounds file <code>''name''.snd</code> in the [[Sound Player]] tool. (Sounds can also be opened by choosing '''C4 > Open Sound'''.)}} |- {{Tablerow|<code>texture</code> ''name''|Opens the texture file <code>''name''.tex</code> in the [[Texture Viewer]] tool. (Textures can also be opened by choosing '''C4 > Open Texture'''.)}} |- {{Tablerow|<code>world</code> ''name''|Opens the world file <code>''name''.wld</code> in the [[World Editor]] tool. (Worlds can also be opened by choosing '''C4 > Open World'''.)}} |} == Defining New Commands == Application modules and plugin modules can add their own commands to the engine by creating new instances of the <code>Command</code> class. The constructor for the <code>Command</code> class takes a command string and a pointer to an observer object that is invoked when the command is executed. For example, to define a command called explode that causes the <code>MyClass::ExplodeFunction()</code> function to be called, you would construct a new <code>Command</code> instance as follows. <syntaxhighlight lang="c++"> CommandObserver<MyClass> explodeObserver(this, &MyClass::ExplodeFunction); Command *explodeCommand = new Command("explode", &explodeObserver); </syntaxhighlight> Once the command has been constructed, it needs to be added to the engine's command list before it will be recognized. This is done by calling the <code>Engine::AddCommand()</code> function. Continuing the explode example, you would make the following call to add the explode command to the engine. <syntaxhighlight lang="c++"> TheEngine->AddCommand(explodeCommand); </syntaxhighlight> Destroying the <code>Command</code> instance automatically removes the command from the engine. The observer event handling function assigned to a new command must have the following prototype. <syntaxhighlight lang="c++"> void ExplodeFunction(Command *command, const char *text); </syntaxhighlight> When a command is entered into the console (or executed from a file), the observer event handler is invoked, and the text passed in through the text parameter provides the rest of the command line. For instance, the command <code>explode 1 boom</code> would cause the <code>ExplodeFunction()</code> function to be called with a pointer to the string <code>"1 boom"</code>. == Console Output == You can write text to the Command Console window by calling the <code>Engine::Report()</code> function. The string passed to the <code>Engine::Report()</code> function is output to the console whenever the <code>flags</code> parameter does not include the bit <code>kReportLog</code>. For example, to write some integer value to the console with a text label, you could make the following call: <syntaxhighlight lang="c++"> Engine::Report(String<63>("My value is now ") += myValue); </syntaxhighlight> (The number 63 represents the maximum length of the string stored in the <code>String</code> object. This number can be omitted altogether to get an arbitrarily large string, but it causes extra memory allocations.) == Disabling the Console == The Command Console window can be opened when the keyboard is in either interface mode or game input mode, and both of these methods must be disabled in order to prevent access to the console. To make the Command Console window completely inaccessible, make the following two function calls: <syntaxhighlight lang="c++"> TheInputMgr->SetConsoleCallback(nullptr); TheInterfaceMgr->DisableConsole(); </syntaxhighlight> If the Command Console window is later going to be enabled again, then it will also be necessary to save the previous console procedure so that it can be restored. This can be done by expanding the above code as follows: <syntaxhighlight lang="c++"> // Declared in some larger scope: InputMgr::KeyCallback savedConsoleCallback; void *savedConsoleCookie; ... savedConsoleCallback = TheInputMgr->GetConsoleCallback(); savedConsoleCookie = TheInputMgr->GetConsoleCookie(); TheInputMgr->SetConsoleCallback(nullptr); TheInterfaceMgr->DisableConsole(); </syntaxhighlight> To enable the Command Console window again and restore the previous console procedure in the Input Manager, use the following code: <syntaxhighlight lang="c++"> TheInputMgr->SetConsoleProc(savedConsoleProc, savedConsoleCookie); TheInterfaceMgr->EnableConsole(); </syntaxhighlight> == See Also == * [[C4 Menu]] * [[List of System Variables]] e14d4967486b6dd2c5692fcf8657f8a15aadf44c 549 548 2024-11-27T09:12:03Z Eric Lengyel 1 /* Core Engine Commands */ wikitext text/x-wiki [[File:Console.png|480px|right]] The '''Command Console''' window can be opened at any time by pressing the tilde/grave key. (On some non-English keyboards, the key directly below the Escape key should be used.) The window displays a command line and an output buffer as shown in the image to the right. If the C4 Engine was built using the debug settings, the window displays "(Debug)" to the right of the build number. The console stores a small command history that can be accessed with the up and down arrow keys. __TOC__ <br clear="right" /> == Core Engine Commands == The following table describes some of the commands that are built into the engine. New commands can be added by an application or plugin module (see below). {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|<code>address</code>|Displays the IP address of the local machine. Must be in a network game.}} |- {{Tablerow|<code>bind</code> ''key'' <code>"</code>''command''<code>"</code>|Binds the key whose name is ''key'' to the command specified by ''command''. Whenever the bound key is pressed in gameplay mode, the specified command is executed.}} |- {{Tablerow|<code>body</code>|Toggles the display of bounding boxes for active rigid bodies.}} |- {{Tablerow|<code>cmd</code>|Displays a list of available console commands.}} |- {{Tablerow|<code>disconnect</code>|Disconnects from a multiplayer game.}} |- {{Tablerow|<code>dump</code>|Writes a list of all currently allocated memory blocks to the file <code>Memory.txt</code>. Leak detection must be turned on.}} |- {{Tablerow|<code>exec</code> ''path''|Executes the file <code>Data/*/''path''.cfg</code>.}} |- {{Tablerow|<code>gentex</code>|Opens the [[Texture Generation]] tool, which renders textures for light projections, environment maps, and impostor textures. (Can only be invoked while a game world is running.)}} |- {{Tablerow|<code>heap</code>|(Advanced) Displays memory heap totals in the console.}} |- {{Tablerow|<code>load</code> ''name''|Loads the world <code>''name''.wld</code> for gameplay.}} |- {{Tablerow|<code>lrgn</code>|(Advanced) Toggles the display of light regions.}} |- {{Tablerow|<code>net</code>|Opens the Network window, which displays various network statistics. (The Network window can also be opened by choosing '''C4 > Network Window'''.)}} |- {{Tablerow|<code>norm</code>|Toggles the display of normal vectors.}} |- {{Tablerow|<code>quit</code>|Quits the C4 Engine.}} |- {{Tablerow|<code>record</code> ''name''|Starts recording video and/or audio to files that can later be imported as a movie. See [[Recording Movies]] for more information.}} |- {{Tablerow|<code>resolve</code> ''hostname''|Resolves a host name to an IP address. Must be in a network game.}} |- {{Tablerow|<code>restore</code> ''name''|Restore the previously saved game <code>Save/''name''.sav</code>.}} |- {{Tablerow|<code>save</code> ''name''|Save the current game as <code>Save/''name''.sav</code>.}} |- {{Tablerow|<code>say</code> <code>"</code>''message''<code>"</code>|Sends a chat message to all players in the current multiplayer game.}} |- {{Tablerow|<code>shot</code> ''name''|Takes a [[Screenshots|screenshot]] and saves it as <code>''name''.tga</code> in the user's Documents directory in a subfolder named C4 Engine. If a <code>#</code> character appears in the name, then the name from that point on is replaced with a screenshot count that starts at 1 and gets incremented each time it is used in a screenshot name.}} |- {{Tablerow|<code>smap</code> ''type''|(Advanced) Opens the Shadow Map window for a particular light type. The value of ''type'' must be <code>inft</code>, <code>pont</code>, or <code>spot</code>.}} |- {{Tablerow|<code>spth</code>|(Advanced) Toggles the display of sound flow paths.}} |- {{Tablerow|<code>stat</code>|Opens the Stats window, which displays various engine statistics. (The Stats window can also be accessed by choosing '''C4 > Stats Window'''.)}} |- {{Tablerow|<code>tang</code>|Toggles the display of tangent vectors.}} |- {{Tablerow|<code>target</code> ''type''|(Advanced) Opens the Target window, which displays one of the offscreen render targets. The value of ''type'' can be one of the following: * <code>strc</code> &ndash; linear depth in structure buffer * <code>grad</code> &ndash; gradient in structure buffer * <code>occl</code> &ndash; ambient occlusion buffer * <code>dist</code> &ndash; distortion buffer * <code>velo</code> &ndash; velocity buffer * <code>atms</code> &ndash; atmospheric shadowing buffer * <code>glbl</code> &ndash; glow/bloom buffer}} |- {{Tablerow|<code>time</code>|Opens the Time window, which displays the frame rate in frames/s and ms/frame, the current load on the GPU and CPU, and a detailed breakdown of the time the engine spends on specific features such as shadows and post processing. (The Time window can also be opened by choosing '''C4 > Time Window'''.)}} |- {{Tablerow|<code>tone</code>|(Advanced) Opens the Tone Mapping window, which displays a luminance histogram and tone mapping curve.}} |- {{Tablerow|<code>unbind</code> ''key''|Unbinds the key whose name is ''key''.}} |- {{Tablerow|<code>undef</code> ''name''|Undefines the variable ''name'', if the variable is not permanent.}} |- {{Tablerow|<code>unload</code>|Unloads the current gameplay world.}} |- {{Tablerow|<code>var</code>|Displays a list of currently defined system variables.}} |- {{Tablerow|<code>wire</code>|Toggles the display of the wireframe overlay.}} |} == Tool Commands == The following commands are defined by the standard tools that ship with the C4 Engine. Most of these commands have equivalent items in the [[C4 Menu]]. If the ''name'' parameter is omitted from any of these commands, then a file picker dialog will appear to let you select a file. {| {{Table}} {{Tablehead|Command|Description}} |- {{Tablerow|<code>ifont</code>|Opens the [[Font Importer]] tool. (This tool can also be opened by choosing '''C4 > Import Font'''.)}} |- {{Tablerow|<code>imovie</code>|Opens the [[Movie Importer]] tool. (Movies can also be imported by choosing '''C4 > Import Movie'''.)}} |- {{Tablerow|<code>isound</code> ''name''|Imports the sound file <code>''name''.wav</code>. See also [[Sound Importer]]. (Sounds can also be imported by choosing '''C4 > Import Sound'''.)}} |- {{Tablerow|<code>istring</code> ''name''|Imports the string table file <code>''name''.txt</code>. See also [[String Tables]]. (String tables can also be imported by choosing '''C4 > Import String Table'''.)}} |- {{Tablerow|<code>itexture</code> ''name''|Imports the texture file <code>''name''.tga</code>. See also [[Texture Importer]]. (Textures can also be imported by choosing '''C4 > Import Texture'''.)}} |- {{Tablerow|<code>model</code> ''name''|Opens the model file <code>''name''.mdl</code> in the [[Model Viewer]] tool. (Models can also be opened by choosing '''C4 > Open Model'''.)}} |- {{Tablerow|<code>movie</code> ''name''|Opens the movie file <code>''name''.mvi</code> in the [[Movie Player]] tool. (Movies can also be opened by choosing '''C4 > Open Movie'''.)}} |- {{Tablerow|<code>pack</code> ''name''|Creates a pack file, where ''name'' is the name of a top-level subfolder in the <code>Data</code> directory. See also [[Pack Files and Virtual Directories]].}} |- {{Tablerow|<code>panel</code> ''name''|Opens the panel file <code>''name''.pan</code> in the [[Panel Editor]] tool. (Panels can also be opened by choosing '''C4 > Open Panel'''.)}} |- {{Tablerow|<code>sound</code> ''name''|Opens the sounds file <code>''name''.snd</code> in the [[Sound Player]] tool. (Sounds can also be opened by choosing '''C4 > Open Sound'''.)}} |- {{Tablerow|<code>texture</code> ''name''|Opens the texture file <code>''name''.tex</code> in the [[Texture Viewer]] tool. (Textures can also be opened by choosing '''C4 > Open Texture'''.)}} |- {{Tablerow|<code>world</code> ''name''|Opens the world file <code>''name''.wld</code> in the [[World Editor]] tool. (Worlds can also be opened by choosing '''C4 > Open World'''.)}} |} == Defining New Commands == Application modules and plugin modules can add their own commands to the engine by creating new instances of the <code>Command</code> class. The constructor for the <code>Command</code> class takes a command string and a pointer to an observer object that is invoked when the command is executed. For example, to define a command called explode that causes the <code>MyClass::ExplodeFunction()</code> function to be called, you would construct a new <code>Command</code> instance as follows. <syntaxhighlight lang="c++"> CommandObserver<MyClass> explodeObserver(this, &MyClass::ExplodeFunction); Command *explodeCommand = new Command("explode", &explodeObserver); </syntaxhighlight> Once the command has been constructed, it needs to be added to the engine's command list before it will be recognized. This is done by calling the <code>Engine::AddCommand()</code> function. Continuing the explode example, you would make the following call to add the explode command to the engine. <syntaxhighlight lang="c++"> TheEngine->AddCommand(explodeCommand); </syntaxhighlight> Destroying the <code>Command</code> instance automatically removes the command from the engine. The observer event handling function assigned to a new command must have the following prototype. <syntaxhighlight lang="c++"> void ExplodeFunction(Command *command, const char *text); </syntaxhighlight> When a command is entered into the console (or executed from a file), the observer event handler is invoked, and the text passed in through the text parameter provides the rest of the command line. For instance, the command <code>explode 1 boom</code> would cause the <code>ExplodeFunction()</code> function to be called with a pointer to the string <code>"1 boom"</code>. == Console Output == You can write text to the Command Console window by calling the <code>Engine::Report()</code> function. The string passed to the <code>Engine::Report()</code> function is output to the console whenever the <code>flags</code> parameter does not include the bit <code>kReportLog</code>. For example, to write some integer value to the console with a text label, you could make the following call: <syntaxhighlight lang="c++"> Engine::Report(String<63>("My value is now ") += myValue); </syntaxhighlight> (The number 63 represents the maximum length of the string stored in the <code>String</code> object. This number can be omitted altogether to get an arbitrarily large string, but it causes extra memory allocations.) == Disabling the Console == The Command Console window can be opened when the keyboard is in either interface mode or game input mode, and both of these methods must be disabled in order to prevent access to the console. To make the Command Console window completely inaccessible, make the following two function calls: <syntaxhighlight lang="c++"> TheInputMgr->SetConsoleCallback(nullptr); TheInterfaceMgr->DisableConsole(); </syntaxhighlight> If the Command Console window is later going to be enabled again, then it will also be necessary to save the previous console procedure so that it can be restored. This can be done by expanding the above code as follows: <syntaxhighlight lang="c++"> // Declared in some larger scope: InputMgr::KeyCallback savedConsoleCallback; void *savedConsoleCookie; ... savedConsoleCallback = TheInputMgr->GetConsoleCallback(); savedConsoleCookie = TheInputMgr->GetConsoleCookie(); TheInputMgr->SetConsoleCallback(nullptr); TheInterfaceMgr->DisableConsole(); </syntaxhighlight> To enable the Command Console window again and restore the previous console procedure in the Input Manager, use the following code: <syntaxhighlight lang="c++"> TheInputMgr->SetConsoleProc(savedConsoleProc, savedConsoleCookie); TheInterfaceMgr->EnableConsole(); </syntaxhighlight> == See Also == * [[C4 Menu]] * [[List of System Variables]] 6b8a8b031924691a7fe1d76d5658165e2c8d1580 Defining a Custom Controller 0 119 532 121 2023-09-12T21:37:04Z Eric Lengyel 1 wikitext text/x-wiki In the C4 Engine, a ''controller'' is attached to a node to give it some kind of dynamic behavior. A controller is represented by a subclass of the [http://c4engine.com/docs/Controller/Controller.html <code>Controller</code>] class and contains all of the information needed to move or change an object in some way. It is often the case that a controller is assigned to a node and configured in the World Editor under the Controller tab in the Node Info window. == Defining a Controller Subclass == In this article, we will use the example of a controller called <code>TwistController</code> that simply twists a node around its ''z'' axis. Note that this particular functionality already exists as part of the more general built-in [[Spin Controller]], so the example here is for illustrative purposes only. A custom controller subclass needs to have a unique type identifier that is registered with the engine so that the [[World Editor]] knows about it. The type identifier is a 32-bit number normally represented by a four-character string as in the following code. <syntaxhighlight lang="cpp"> enum { kControllerTwist = 'twst' }; </syntaxhighlight> (Type identifiers consisting of only uppercase letters and numbers are reserved for use by the engine. Anything else is okay for an application to use.) Next, the controller subclass needs to be defined. We declare the <code>TwistController</code> class to be a subclass of the <code>Controller</code> class as follows. We include some data members, one of which holds the rate at which the target node should twist. Several member functions are included to handle serialization and user interface&mdash;these are discussed below. <syntaxhighlight lang="cpp"> class TwistController : public Controller { private: float twistRate; // In radians per millisecond. float twistAngle; // The current angle, in radians. Transform4D originalTransform; // The target's original transform. TwistController(const TwistController& twistController); Controller *Replicate(void) const; public: TwistController(); TwistController(float rate); ~TwistController(); float GetTwistRate(void) const { return (twistRate); } void SetTwistRate(float rate) { twistRate = rate; } static bool ValidNode(const Node *node); // Serialization functions. void Pack(Packer& data, uint32 packFlags) const override; void Unpack(Unpacker& data, uint32 unpackFlags) override; // User interface functions. void BuildSettingList(List<Setting> *settingList) const override; void CommitSetting(const Setting *setting) override; void PreprocessController(void); // The function that moves the target node. void MoveController(void); }; </syntaxhighlight> The constructor and destructor for this example would typically be implemented as follows. <syntaxhighlight lang="cpp"> TwistController::TwistController() : Controller(kControllerTwist) { // Set a default value for the twist rate of one revolution per second. twistRate = Math::two_pi / 1000.0F; twistAngle = 0.0F; } TwistController::TwistController(float rate) : Controller(kControllerTwist) { twistRate = rate; twistAngle = 0.0F; } TwistController::~TwistController() { } </syntaxhighlight> Notice that the controller's type <code>kControllerTwist</code> is passed to the base class's constructor. The default constructor only needs to set a default value if the controller will be exposed in the World Editor. Otherwise, the default constructor will only be called right before the controller is deserialized, thus filling in the data members. The copy constructor and the <code>Replicate()</code> function must be included for all controllers. For this example, the copy constructor would be implemented as follows. <syntaxhighlight lang="cpp"> TwistController::TwistController(const TwistController& twistController) : Controller(twistController) { twistRate = twistController.twistRate; twistAngle = 0.0F; } </syntaxhighlight> It's important to observe that the reference to the copied <code>TwistController</code> object is passed to the base class constructor this time instead of the controller's type identifier. The <code>Replicate()</code> function simply constructs a new instance of the controller using the copy constructor. This would usually be implemented as follows. <syntaxhighlight lang="c++"> Controller *TwistController::Replicate(void) const { return (new TwistController(*this)); } </syntaxhighlight> == Controller Registration == A custom controller type must be registered with the engine in order to be recognized by the World Editor. This is accomplished by creating a ControllerReg object. The controller registration contains information about the controller type and its name, and it's mere existence registers the controller type that it represents. A controller registration for the TwistController class would normally look like the following. <syntaxhighlight lang="cpp"> // Define the controller registration. ControllerReg<TwistController> twistControllerReg; </syntaxhighlight> The registration object is initialized with the following code. <syntaxhighlight lang="cpp"> twistControllerReg(kControllerTwist, "Twist"); </syntaxhighlight> The <code>ValidNode()</code> function declared in the <code>TwistController</code> class is used by the World Editor to determine what kind of node the controller was meant to be assigned to. If this function is not included in the class definition, then the controller can be assigned to any node. Otherwise, the <code>ValidNode()</code> function should return <code>true</code> when it's okay to assign the controller to the node passed to it, and <code>false</code> if it's not okay. As an example, if we only wanted <code>TwistController</code> objects to be assigned to geometry nodes, then we would implement the <code>ValidNode()</code> function as follows. <syntaxhighlight lang="c++"> bool TwistController::ValidNode(const Node *node) { return (node->GetNodeType() == kNodeGeometry); } </syntaxhighlight> Notice that the <code>ValidNode()</code> function is declared <code>static</code>. The World Editor calls this function automatically when it needs to know whether the controller can be used with a specific node. == Serialization == A custom controller must implement the <code>Pack()</code> and <code>Unpack()</code> functions so that its data can be written to a file and later restored. (These functions override the virtual functions in the [http://c4engine.com/docs/ResourceMgr/Packable.html <code>Packable</code>] class.) Each of these functions needs to first call its counterpart in the <code>Controller</code> base class. For the <code>TwistController</code> example, these functions would typically be implemented as follows. <syntaxhighlight lang="cpp"> void TwistController::Pack(Packer& data, uint32 packFlags) const { Controller::Pack(data, packFlags); // Write the twist rate. data << twistRate; // Write the current angle. data << twistAngle; // Write the original transform. data << originalTransform; } void TwistController::Unpack(Unpacker& data, uint32 unpackFlags) { Controller::Unpack(data, unpackFlags); // Read the twist rate. data >> twistRate; // Read the current angle. data >> twistAngle; // Read the original transform. data >> originalTransform; } </syntaxhighlight> == User Interface == The <code>Controller</code> class is a subclass of the [http://c4engine.com/docs/InterfaceMgr/Configurable.html <code>Configurable</code>] class, which means it can expose a user interface that appears in the [[World Editor]]. The <code>Controller</code> object is queried by the World Editor for its configurable settings when the user opens the Node Info window for a node with a controller attached to it. The <code>BuildSettingList()</code> function is called when the editor needs all of the configurable settings to be built, and the <code>CommitSetting()</code> function is called for each setting when the user confirms the new configuration. For the <code>TwistController</code> example, there is one setting representing the twist rate stored in the controller object. The user interface to change this value would be implemented as follows. <syntaxhighlight lang="cpp"> void TwistController::BuildSettingList(List<Setting> *settingList) const { // There is one setting, and it's an editable text field. settingList->AppendListElement(new TextSetting('rate', "Twist rate", Text::FloatToString(twistRate * 1000.0F / Math::two_pi))); } void TwistController::CommitSetting(const Setting *setting) { // Are we setting the twist rate? if (setting->GetSettingIdentifier() == 'rate') { // Yes, grab the rate value from the setting. const char *text = static_cast<const TextSetting *>(setting)->GetText(); twistRate = Text::StringToFloat(text) * Math::two_pi * 0.001F; } } </syntaxhighlight> The first parameter passed to the <code>TextSetting</code> constructor (<code>'rate'</code>) is just an identifier that the controller uses to keep track of which setting is which&mdash;it can be anything you want. The second parameter is the title of the setting that, in this case, will be displayed next to the editable text box. The third parameter is the value that will initially be shown to the user. == Moving the Target Node == The <code>PreprocessController()</code> function is called once when the controller's target node is inserted into a world. In this function, we record the original transformation matrix for the target node so that we have a reference frame to which rotations are later going to be applied. We also make sure that the <code>kGeometryDynamic</code> flag is set for any geometry nodes in the subtree rooted at the target node. This tells the engine not to cache certain types of information for the objects that we're going to be moving. The body of our <code>PreprocessController()</code> function is shown below. Note that the base class's <code>PreprocessController()</code> function should always be called. <syntaxhighlight lang="cpp"> void TwistController::PreprocessController(void) { PreprocessController::Preprocess(); // Grab the original transform of the target node. const Node *target = GetTargetNode(); originalTransform = target->GetNodeTransform(); // Set the kGeometryDynamic flag for any geometry nodes. const Node *node = target; do { if (node->GetNodeType() == kNodeGeometry) { // Node is a geometry, so grab its object. GeometryObject *object = static_cast<const Geometry *>(node)->GetObject(); // Set the kGeometryDynamic flag. object->SetGeometryFlags(object->GetGeometryFlags() | kGeometryDynamic); } // Iterate through entire subtree. node = target->GetNextTreeNode(node); } while (node); } </syntaxhighlight> The <code>MoveController()</code> function is called once per frame to let the controller move its target node. In the case of the <code>TwistController</code> class, we just want to update the twist angle and calculate a new transform for the target node. The body of our <code>MoveController()</code> function looks like the following. (We do not need to call the base class's <code>MoveController()</code> function.) <syntaxhighlight lang="cpp"> void TwistController::MoveController(void) { Matrix3D rotator; // Calculate the new twist angle based on how much time has passed. float angle = twistAngle + twistRate * TheTimeMgr->GetFloatDeltaTime(); // Make sure it's in the [-pi, pi] range. if (angle > Math::pi) angle -= Math::two_pi; else if (angle < -Math::pi) angle += Math::two_pi; twistAngle = angle; // Now make a 3x3 rotation matrix. rotator.SetRotationAboutZ(angle); // We'll rotate about the object-space center of the target node's bounding box. Node *target = GetTargetNode(); Point3D objectCenter = target->GetInverseWorldTransform() * target->GetBoundingBox()->GetCenter(); // Make a 3x4 transform that rotates about the center point. Transform4D transform(rotator, objectCenter - rotator * objectCenter); // Apply the rotation transform to the original transform and // assign it to the node as its new transform. target->SetNodeTransform(originalTransform * transform); // Invalidate the target node so that it gets updated properly. target->InvalidateNode(); } </syntaxhighlight> == See Also == * [http://c4engine.com/docs/Controller/Controller.html <code>Controller</code> class] * [http://c4engine.com/docs/Controller/ControllerReg.html <code>ControllerReg</code> class] [[Category:Controllers]] 2ceb99cf394aa61f973503f5fbf8b5a348ba716e 541 532 2023-12-08T01:19:52Z Eric Lengyel 1 wikitext text/x-wiki In the C4 Engine, a ''controller'' is attached to a node to give it some kind of dynamic behavior. A controller is represented by a subclass of the [http://c4engine.com/docs/Controller/Controller.html <code>Controller</code>] class and contains all of the information needed to move or change an object in some way. It is often the case that a controller is assigned to a node and configured in the World Editor under the Controller tab in the Node Info window. == Defining a Controller Subclass == In this article, we will use the example of a controller called <code>TwistController</code> that simply twists a node around its ''z'' axis. Note that this particular functionality already exists as part of the more general built-in [[Spin Controller]], so the example here is for illustrative purposes only. A custom controller subclass needs to have a unique type identifier that is registered with the engine so that the [[World Editor]] knows about it. The type identifier is a 32-bit number normally represented by a four-character string as in the following code. <syntaxhighlight lang="cpp"> enum { kControllerTwist = 'twst' }; </syntaxhighlight> (Type identifiers consisting of only uppercase letters and numbers are reserved for use by the engine. Anything else is okay for an application to use.) Next, the controller subclass needs to be defined. We declare the <code>TwistController</code> class to be a subclass of the <code>Controller</code> class as follows. We include some data members, one of which holds the rate at which the target node should twist. Several member functions are included to handle serialization and user interface&mdash;these are discussed below. <syntaxhighlight lang="cpp"> class TwistController : public Controller { private: float twistRate; // In radians per millisecond. float twistAngle; // The current angle, in radians. Transform4D originalTransform; // The target's original transform. TwistController(const TwistController& twistController); Controller *Replicate(void) const; public: TwistController(); TwistController(float rate); ~TwistController(); float GetTwistRate(void) const { return (twistRate); } void SetTwistRate(float rate) { twistRate = rate; } static bool ValidNode(const Node *node); // Serialization functions. void Pack(Packer& data, uint32 packFlags) const override; void Unpack(Unpacker& data, uint32 unpackFlags) override; // User interface functions. void BuildSettingList(List<Setting> *settingList) const override; void CommitSetting(const Setting *setting) override; void PreprocessController(void); // The function that moves the target node. void MoveController(void); }; </syntaxhighlight> The constructor and destructor for this example would typically be implemented as follows. <syntaxhighlight lang="cpp"> TwistController::TwistController() : Controller(kControllerTwist) { // Set a default value for the twist rate of one revolution per second. twistRate = Math::two_pi / 1000.0F; twistAngle = 0.0F; } TwistController::TwistController(float rate) : Controller(kControllerTwist) { twistRate = rate; twistAngle = 0.0F; } TwistController::~TwistController() { } </syntaxhighlight> Notice that the controller's type <code>kControllerTwist</code> is passed to the base class's constructor. The default constructor only needs to set a default value if the controller will be exposed in the World Editor. Otherwise, the default constructor will only be called right before the controller is deserialized, thus filling in the data members. The copy constructor and the <code>Replicate()</code> function must be included for all controllers. For this example, the copy constructor would be implemented as follows. <syntaxhighlight lang="cpp"> TwistController::TwistController(const TwistController& twistController) : Controller(twistController) { twistRate = twistController.twistRate; twistAngle = 0.0F; } </syntaxhighlight> It's important to observe that the reference to the copied <code>TwistController</code> object is passed to the base class constructor this time instead of the controller's type identifier. The <code>Replicate()</code> function simply constructs a new instance of the controller using the copy constructor. This would usually be implemented as follows. <syntaxhighlight lang="c++"> Controller *TwistController::Replicate(void) const { return (new TwistController(*this)); } </syntaxhighlight> == Controller Registration == A custom controller type must be registered with the engine in order to be recognized by the World Editor. This is accomplished by creating a ControllerReg object. The controller registration contains information about the controller type and its name, and it's mere existence registers the controller type that it represents. A controller registration for the TwistController class would normally look like the following. <syntaxhighlight lang="cpp"> // Define the controller registration. ControllerReg<TwistController> twistControllerReg; </syntaxhighlight> The registration object is initialized with the following code. <syntaxhighlight lang="cpp"> twistControllerReg(kControllerTwist, "Twist"); </syntaxhighlight> The <code>ValidNode()</code> function declared in the <code>TwistController</code> class is used by the World Editor to determine what kind of node the controller was meant to be assigned to. If this function is not included in the class definition, then the controller can be assigned to any node. Otherwise, the <code>ValidNode()</code> function should return <code>true</code> when it's okay to assign the controller to the node passed to it, and <code>false</code> if it's not okay. As an example, if we only wanted <code>TwistController</code> objects to be assigned to geometry nodes, then we would implement the <code>ValidNode()</code> function as follows. <syntaxhighlight lang="c++"> bool TwistController::ValidNode(const Node *node) { return (node->GetNodeType() == kNodeGeometry); } </syntaxhighlight> Notice that the <code>ValidNode()</code> function is declared <code>static</code>. The World Editor calls this function automatically when it needs to know whether the controller can be used with a specific node. == Serialization == A custom controller must implement the <code>Pack()</code> and <code>Unpack()</code> functions so that its data can be written to a file and later restored. (These functions override the virtual functions in the [http://c4engine.com/docs/ResourceMgr/Packable.html <code>Packable</code>] class.) Each of these functions needs to first call its counterpart in the <code>Controller</code> base class. For the <code>TwistController</code> example, these functions would typically be implemented as follows. <syntaxhighlight lang="cpp"> void TwistController::Pack(Packer& data, uint32 packFlags) const { Controller::Pack(data, packFlags); // Write the twist rate. data << twistRate; // Write the current angle. data << twistAngle; // Write the original transform. data << originalTransform; } void TwistController::Unpack(Unpacker& data, uint32 unpackFlags) { Controller::Unpack(data, unpackFlags); // Read the twist rate. data >> twistRate; // Read the current angle. data >> twistAngle; // Read the original transform. data >> originalTransform; } </syntaxhighlight> == User Interface == The <code>Controller</code> class is a subclass of the [http://c4engine.com/docs/InterfaceMgr/Configurable.html <code>Configurable</code>] class, which means it can expose a user interface that appears in the [[World Editor]]. The <code>Controller</code> object is queried by the World Editor for its configurable settings when the user opens the Node Info window for a node with a controller attached to it. The <code>BuildSettingList()</code> function is called when the editor needs all of the configurable settings to be built, and the <code>CommitSetting()</code> function is called for each setting when the user confirms the new configuration. For the <code>TwistController</code> example, there is one setting representing the twist rate stored in the controller object. The user interface to change this value would be implemented as follows. <syntaxhighlight lang="cpp"> void TwistController::BuildSettingList(List<Setting> *settingList) const { // There is one setting, and it's an editable text field. settingList->AppendListElement(new TextSetting('rate', "Twist rate", Text::FloatToString(twistRate * 1000.0F / Math::two_pi))); } void TwistController::CommitSetting(const Setting *setting) { // Are we setting the twist rate? if (setting->GetSettingIdentifier() == 'rate') { // Yes, grab the rate value from the setting. const char *text = static_cast<const TextSetting *>(setting)->GetText(); twistRate = Text::StringToFloat(text) * Math::two_pi * 0.001F; } } </syntaxhighlight> The first parameter passed to the <code>TextSetting</code> constructor (<code>'rate'</code>) is just an identifier that the controller uses to keep track of which setting is which&mdash;it can be anything you want. The second parameter is the title of the setting that, in this case, will be displayed next to the editable text box. The third parameter is the value that will initially be shown to the user. == Moving the Target Node == The <code>PreprocessController()</code> function is called once when the controller's target node is inserted into a world. In this function, we record the original transformation matrix for the target node so that we have a reference frame to which rotations are later going to be applied. We also make sure that the <code>kGeometryDynamic</code> flag is set for any geometry nodes in the subtree rooted at the target node. This tells the engine not to cache certain types of information for the objects that we're going to be moving. The body of our <code>PreprocessController()</code> function is shown below. Note that the base class's <code>PreprocessController()</code> function should always be called. <syntaxhighlight lang="cpp"> void TwistController::PreprocessController(void) { PreprocessController::Preprocess(); // Grab the original transform of the target node. const Node *target = GetTargetNode(); originalTransform = target->GetNodeTransform(); // Set the kGeometryDynamic flag for any geometry nodes. const Node *node = target; do { if (node->GetNodeType() == kNodeGeometry) { // Node is a geometry, so grab its object. GeometryObject *object = static_cast<const Geometry *>(node)->GetObject(); // Set the kGeometryDynamic flag. object->SetGeometryFlags(object->GetGeometryFlags() | kGeometryDynamic); } // Iterate through entire subtree. node = target->GetNextTreeNode(node); } while (node); } </syntaxhighlight> The <code>MoveController()</code> function is called once per frame to let the controller move its target node. In the case of the <code>TwistController</code> class, we just want to update the twist angle and calculate a new transform for the target node. The body of our <code>MoveController()</code> function looks like the following. (We do not need to call the base class's <code>MoveController()</code> function.) <syntaxhighlight lang="cpp"> void TwistController::MoveController(void) { // Calculate the new twist angle based on how much time has passed. float angle = twistAngle + twistRate * TheTimeMgr->GetFloatDeltaTime(); // Make sure it's in the [-pi, pi] range. if (angle > Math::pi) angle -= Math::two_pi; else if (angle < -Math::pi) angle += Math::two_pi; twistAngle = angle; // Now make a 3x3 rotation matrix. Matrix3D rotator = Matrix3D::MakeRotationZ(angle); // We'll rotate about the object-space center of the target node's bounding box. Node *target = GetTargetNode(); Point3D objectCenter = target->GetInverseWorldTransform() * target->GetBoundingBox()->GetCenter(); // Make a 3x4 transform that rotates about the center point. Transform4D transform(rotator, objectCenter - rotator * objectCenter); // Apply the rotation transform to the original transform and // assign it to the node as its new transform. target->SetNodeTransform(originalTransform * transform); // Invalidate the target node so that it gets updated properly. target->InvalidateNode(); } </syntaxhighlight> == See Also == * [http://c4engine.com/docs/Controller/Controller.html <code>Controller</code> class] * [http://c4engine.com/docs/Controller/ControllerReg.html <code>ControllerReg</code> class] [[Category:Controllers]] 50b32cafb65b58c76125f98d281777ed02abb07e Defining a Custom Method 0 120 533 122 2023-09-12T21:38:02Z Eric Lengyel 1 wikitext text/x-wiki In the C4 Engine, a ''method'' refers to an individual action that can appear in a script. There are many types of methods built into the engine, and an application can define its own custom methods by implementing new subclasses of the [http://c4engine.com/docs/Controller/Method.html Method] class. == Defining a Method Subclass == In this article, we will use the example of a method called <code>ChangeLightColorMethod</code> that simply changes the color of a light source. Note that this particular functionality already exists as part of the more general built-in method '''Change Settings''', so the example here is for illustrative purposes only. A custom method subclass needs to have a unique type identifier that is registered with the engine so that the [[Script Editor]] knows about it. The type identifier is a 32-bit number normally represented by a four-character string as in the following code. <syntaxhighlight lang="c++"> enum { kMethodChangeLightColor = 'litc' }; </syntaxhighlight> (Type identifiers consisting of only uppercase letters and numbers are reserved for use by the engine. Anything else is okay for an application to use.) Next, the method subclass needs to be defined. We declare the <code>ChangeLightColorMethod</code> class to be a subclass of the <code>Method</code> class as follows, and we include a single data member to hold the color value that will be assigned to a light source when the method executes. Several member functions are included to handle serialization and user interface&mdash;these are discussed below. <syntaxhighlight lang="c++"> class ChangeLightColorMethod : public Method { private: ColorRGB lightColor; ChangeLightColorMethod(const ChangeLightColorMethod& changeLightColorMethod); Method *Replicate(void) const; public: ChangeLightColorMethod(); ChangeLightColorMethod(const ColorRGB& color); ~ChangeLightColorMethod(); const ColorRGB& GetLightColor(void) const { return (lightColor); } void SetLightColor(const ColorRGB& color) { lightColor = color; } // Serialization functions. void Pack(Packer& data, uint32 packFlags) const override; void Unpack(Unpacker& data, uint32 unpackFlags) override; // User interface functions. void BuildSettingList(List<Setting> *settingList) const override; void CommitSetting(const Setting *setting) override; // This function is called when the method is executed in a script. void ExecuteMethod(const ScriptState *state) override; }; </syntaxhighlight> The constructor and destructor for this example would typically be implemented as follows. <syntaxhighlight lang="c++"> ChangeLightColorMethod::ChangeLightColorMethod() : Method(kMethodChangeLightColor) { // Set a default value. lightColor.Set(1.0F, 1.0F, 1.0F); } ChangeLightColorMethod::ChangeLightColorMethod(const ColorRGB& color) : Method(kMethodChangeLightColor) { lightColor = color; } ChangeLightColorMethod::~ChangeLightColorMethod() { } </syntaxhighlight> Notice that the method's type <code>kMethodChangeLightColor</code> is passed to the base class constructor. The copy constructor and the <code>Replicate()</code> function must be included for all methods. For this example, the copy constructor would be implemented as follows. <syntaxhighlight lang="c++"> ChangeLightColorMethod::ChangeLightColorMethod(const ChangeLightColorMethod& changeLightColorMethod) : Method(changeLightColorMethod) { lightColor = changeLightColorMethod.lightColor; } </syntaxhighlight> It's important to observe that the reference to the copied <code>ChangeLightColorMethod</code> object is passed to the base class constructor this time instead of the method's type identifier. The <code>Replicate()</code> function simply constructs a new instance of the method using the copy constructor. This should always be implemented as follows. <syntaxhighlight lang="c++"> Method *ChangeLightColorMethod::Replicate(void) const { return (new ChangeLightColorMethod(*this)); } </syntaxhighlight> == Method Registration == A custom method type must be registered with the engine in order to be recognized by the [[Script Editor]]. This is accomplished by creating a <code>MethodReg</code> object. The method registration contains information about the method type and its name, and it's mere existence registers the method type that it represents. A method registration for the <code>ChangeLightColorMethod</code> class would normally look like the following. <syntaxhighlight lang="c++"> // Define the method registration. MethodReg<ChangeLightColorMethod> changeLightColorRegistration; </syntaxhighlight> The registration object is initialized with the following code. <syntaxhighlight lang="c++"> changeLightColorRegistration(kMethodChangeLightColor, "Change Light Color"); </syntaxhighlight> There is an optional third parameter that can specify flags for the method, and these are described in the documentation for the [http://c4engine.com/docs/Controller/MethodReg.html MethodReg] class. == Serialization == A custom method must implement the <code>Pack()</code> and <code>Unpack()</code> functions so that its data can be written to a file and later restored. (These functions override the virtual functions in the [http://c4engine.com/docs/ResourceMgr/Packable.html <code>Packable</code>] class.) Each of these functions needs to first call its counterpart in the <code>Method</code> base class. For the <code>ChangeLightColorMethod</code> example, these functions would typically be implemented as follows. <syntaxhighlight lang="c++"> void ChangeLightColorMethod::Pack(Packer& data, uint32 packFlags) const { Method::Pack(data, packFlags); // Write the ColorRGB object. data << lightColor; } void ChangeLightColorMethod::Unpack(Unpacker& data, uint32 unpackFlags) { Method::Unpack(data, unpackFlags); // Read the ColorRGB object. data >> lightColor; } </syntaxhighlight> == User Interface == The <code>Method</code> class is a subclass of the [http://c4engine.com/docs/InterfaceMgr/Configurable.html <code>Configurable</code>] class, which means it can expose a user interface that appears in the [[Script Editor]]. The <code>Method</code> object is queried by the Script Editor for its configurable settings when the user double-clicks on the method to open its Method Info window. The <code>BuildSettingList()</code> function is called when the editor needs all of the configurable settings to be built, and the <code>CommitSetting()</code> function is called for each setting when the user confirms the new configuration. For the <code>ChangeLightColorMethod</code> example, there is one setting representing the light color stored in the method object. The user interface to change this color would be implemented as follows. <syntaxhighlight lang="c++"> void ChangeLightColorMethod::BuildSettingList(List<Setting> *settingList) const { // There is one setting, and it's a color picker. settingList->AppendListElement(new ColorSetting('colr', lightColor, "Light color", "New Light Color")); } void ChangeLightColorMethod::CommitSetting(const Setting *setting) { // Are we setting the light color? if (setting->GetSettingIdentifier() == 'colr') { // Yes, grab the RGB color from the setting. lightColor = static_cast<const ColorSetting *>(setting)->GetColor().GetColorRGB(); } } </syntaxhighlight> The first parameter passed to the <code>ColorSetting</code> constructor (<code>'colr'</code>) is just an identifier that the property uses to keep track of which setting is which&mdash;it can be anything you want. The second parameter is the color that will initially be shown to the user. The third parameter is the title of the setting that will be displayed next to the color box in the settings list. The last parameter is the title that will be used for the color picker dialog when the user clicks on the color box. == Method Execution == When a script is running and it's time to execute your custom method, the script controller calls the method's <code>ExecuteMethod()</code> function. A method can do anything it wants when it executes as long as it doesn't cause itself to be deleted. When a method finishes performing its actions, it needs to indicate that it has completed by calling the <code>HandleCompletion()</code> function of its [http://c4engine.com/docs/Utilities/Completable.html <code>Completable</code>] base class. A method may finish inside the call to its <code>ExecuteMethod()</code> function, or it may finish sometime later after more time-consuming operations have completed. The <code>ExecuteMethod()</code> function for the <code>ChangeLightColorMethod</code> class could be implemented as follows. <syntaxhighlight lang="c++"> void ChangeLightColorMethod::Execute(const ScriptState *state) { // Get the target node for this method and // make sure it's actually a light source. Node *node = GetTargetNode(state); if ((node) && (node->GetNodeType() == kNodeLight)) { LightObject *object = static_cast<Light *>(node)->GetObject(); // Set the new light color. object->SetLightColor(lightColor); // Mark the object as modified. object->SetModifiedFlag(); } // Indicate that we are finished. HandleCompletion(); } </syntaxhighlight> The call to the <code>GetTargetNode()</code> function retrieves the node that the user has selected as the target of the method in the [[Script Editor]]. It's possible that this target hasn't been selected or that the user linked it to a node that was not a light source, so the above code performs some checks before it carries out its task. Some custom methods do not operate on a target node, and these methods should specify the <code>kMethodNoTarget</code> flag in the method registration so that the user cannot select a target node in the Script Editor. The [http://c4engine.com/docs/WorldMgr/Object_SetModifiedFlag.html <code>SetModifiedFlag()</code>] function should be called whenever an object is modified so that the engine knows to write the object data when a game is saved. If this flag is not set, then the original object data would be reloaded when a saved game is resumed. == Method Output Values == A method may produce an output value that can be stored in a script variable. A method may also generate an independent boolean result that is used for conditional execution of subsequent methods in a script. A method can specify its output value by calling the [http://c4engine.com/docs/Controller/Method_SetOutputValue.html <code>SetOutputValue()</code>] function. When a method outputs a value, it should specify the <code>kMethodOutputValue</code> flag in its method registration so that the [[Script Editor]] allows the user to assign an output variable to the method. If a method calls the <code>SetOutputValue()</code> function, then the boolean result for the method is automatically set according to the output value. A method can set the boolean result without specifying an output value, or it can override the output value, by calling the [http://c4engine.com/docs/Controller/Method_SetMethodResult.html <code>SetMethodResult()</code>] function. == See Also == * [[Script Editor]] * [[Methods]] * [http://c4engine.com/docs/Controller/Method.html <code>Method</code> class] * [http://c4engine.com/docs/Controller/MethodReg.html <code>MethodReg</code> class] [[Category:Scripts]] 1179ee7d600f221e97b6716a5f07e23acc2f5d69 SimpleBall Source Code 0 522 534 2023-09-12T21:41:35Z Eric Lengyel 1 Created page with "This page contains the complete source code for the <code>SimpleBall</code> example game module. See the [[Simple Games]] page for more information about the basic examples. == SimpleBall.h == <syntaxhighlight lang="c++"> #ifndef SimpleBall_h #define SimpleBall_h #include "C4Application.h" #include "C4World.h" #include "C4Input.h" #include "C4Cameras.h" #include "C4Interface.h" #include "C4Particles.h" // Every application/game module needs to declare a function ca..." wikitext text/x-wiki This page contains the complete source code for the <code>SimpleBall</code> example game module. See the [[Simple Games]] page for more information about the basic examples. == SimpleBall.h == <syntaxhighlight lang="c++"> #ifndef SimpleBall_h #define SimpleBall_h #include "C4Application.h" #include "C4World.h" #include "C4Input.h" #include "C4Cameras.h" #include "C4Interface.h" #include "C4Particles.h" // Every application/game module needs to declare a function called CreateApplication() // exactly as follows. (It must be declared extern "C", and it must include the tag // C4_MODULE_EXPORT.) The engine looks for this function in the DLL and calls // it to create an instance of the subclass of the Application class that the // application/game module defines. extern "C" { C4_MODULE_EXPORT C4::Application *CreateApplication(void); } namespace SimpleBall { using namespace C4; // These are action types used to define action bindings in the // Input Manager. If the four-character code for an action is // 'abcd', then any input control (there can be more than one) // bound to %abcd triggers the associated action. enum : ActionType { kActionForward = 'frwd', kActionBackward = 'bkwd', kActionLeft = 'left', kActionRight = 'rght', kActionUp = 'jump', kActionDown = 'down' }; // Model types are associated with a model resource using the ModelRegistration // class. Models are registered with the engine in the Game constructor. enum : ModelType { kModelBall = 'ball' }; // New controller types are registered with the engine in the Game constructor. enum : ControllerType { kControllerBall = 'ball' }; // This is the type of our custom particle system. enum : ParticleSystemType { kParticleSystemSpark = 'sprk' }; // New locator types are registered with the engine in the Game constructor. // The 'spec' locator is used to specify where the spectator camera should // be positioned when a world is loaded. enum : LocatorType { kLocatorSpectator = 'spec' }; // An Action object represents an input action that can be triggered by some // input control, such as a key on the keyboard or a button on a gamepad. // The HandleEngage() and HandleDisengage() methods are called when the button // is pressed and released, respectively. Actions are registered with the Input // Manager when the Game class is constructed. class MovementAction : public Action { private: uint32 movementFlag; public: MovementAction(ActionType type, uint32 flag); ~MovementAction(); void HandleEngage(void) override; void HandleDisengage(void) override; }; // Controllers are used to control anything that moves in the world. // New types of controllers defined by the application/game module are // registered with the engine when the Game class is constructed. // // The BallController inherits from the built-in rigid body controller, // which handles the ball's motion and collision detection. We are only // adding a little bit of functionality that causes a particle system // to be created when a ball hits another ball. class BallController final : public RigidBodyController { private: BallController(const BallController& ballController); Controller *Replicate(void) const override; public: BallController(); ~BallController(); static bool ValidNode(const Node *node); void PreprocessController(void) override; RigidBodyStatus HandleNewRigidBodyContact(const RigidBodyContact *contact, RigidBodyController *contactBody) override; }; // The SparkParticleSystem class implements a simple particle system that // creates a small burst of sparks. class SparkParticleSystem : public LineParticleSystem { // This friend declaration allows the particle system registration object // to construct a SparkParticleSystem object using the private default constructor. friend class ParticleSystemReg<SparkParticleSystem>; private: enum {kMaxParticleCount = 100}; int32 sparkCount; // This is where information about each particle is stored. ParticlePool<> particlePool; Particle particleArray[kMaxParticleCount]; SparkParticleSystem(); bool CalculateBoundingSphere(BoundingSphere *sphere) const override; public: SparkParticleSystem(int32 count); ~SparkParticleSystem(); void PreprocessNode(void) override; void AnimateParticles(void) override; }; // The StartWindow class is a simple example of a window that handles button clicks. // We add the Global base class so that a pointer to the window can be tracked easily. class StartWindow : public C4::Window, public Global<StartWindow> { private: WidgetObserver<StartWindow> startButtonObserver; WidgetObserver<StartWindow> quitButtonObserver; void HandleStartButtonEvent(Widget *widget, const WidgetEventData *eventData); void HandleQuitButtonEvent(Widget *widget, const WidgetEventData *eventData); public: StartWindow(); ~StartWindow(); void PreprocessWidget(void) override; bool HandleKeyboardEvent(const KeyboardEventData *eventData) override; }; // The application/game module will usually define a subclass of the World // class so that extra information can be associated with the current world. // In this case, an instance of the SpectatorCamera class is included // with the world. A new instance of this World subclass should be returned // when the Game::CreateWorld() function is called (see below). class GameWorld : public World { private: SpectatorCamera spectatorCamera; static const LocatorMarker *FindSpectatorLocator(const Zone *zone); public: GameWorld(const char *name); ~GameWorld(); SpectatorCamera *GetSpectatorCamera(void) { return (&spectatorCamera); } WorldResult PreprocessWorld(void) override; void RenderWorld(void) override; }; // Every application/game module needs to define a subclass of the Application // class to serve as the primary interface with the engine. This subclass is // created and returned to the engine in the CreateApplication() function. // There should be only one instance of this class, and a pointer to it is // declared below. class Game : public Application, public Global<Game> { private: ModelRegistration ballModelReg; ControllerReg<BallController> controllerReg; ParticleSystemReg<SparkParticleSystem> sparkParticleSystemReg; LocatorRegistration locatorReg; InputMgr::KeyCallback *prevEscapeCallback; void *prevEscapeCookie; MovementAction *forwardAction; MovementAction *backwardAction; MovementAction *leftAction; MovementAction *rightAction; MovementAction *upAction; MovementAction *downAction; static World *CreateWorld(const char *name, void *cookie); static void EscapeCallback(void *cookie); public: Game(); ~Game(); }; // This is a pointer to the one instance of the Game class through which // any other part of the application/game module can access it. extern Game *TheGame; // This is a pointer to the start window. We only keep this around so that // we can delete the window before exiting if it's still on the screen. extern StartWindow *TheStartWindow; } #endif </syntaxhighlight> == SimpleBall.cpp == <syntaxhighlight lang="c++"> #include "SimpleBall.h" using namespace SimpleBall; // This is the definition of the pointer to the Game class global. // It should be initialized to nullptr, and its value will be set by // the Game class constructor. Game *SimpleBall::TheGame = nullptr; // This is the definition of the pointer to the StartWindow class global. // It should be initialized to nullptr, and its value will be set by // the StartWindow class constructor. StartWindow *SimpleBall::TheStartWindow = nullptr; C4::Application *CreateApplication(void) { // This function should simply return a pointer to a new instance of // the Application class. Normally, the application/game module will // define a subclass of the Application class (in this case, the // Game class) and return a pointer to a new instance of that type. // This function is called exactly one time right after the // application/game module DLL is loaded by the engine. The returned // class is destroyed via the virtual destructor of the Application // class right before the application/game module DLL is unloaded. return (new Game); } MovementAction::MovementAction(ActionType type, uint32 flag) : Action(type) { // Each instance of the MovementAction class represents a movement // in a single direction, as indicated by the flag parameter. // All of the MovementAction instances are constructed in the // Game class constructor. movementFlag = flag; } MovementAction::~MovementAction() { } void MovementAction::HandleEngage(void) { // This function is called when the input control associated with this // particular action is engaged (e.g., a key was pressed). World *world = TheWorldMgr->GetWorld(); if (world) { // If there's currently a world loaded, apply the movement to // the spectator camera. SpectatorCamera *camera = static_cast<GameWorld *>(world)->GetSpectatorCamera(); camera->SetSpectatorFlags(camera->GetSpectatorFlags() | movementFlag); } } void MovementAction::HandleDisengage(void) { // This function is called when the input control associated with this // particular action is disengaged (e.g., a key was released). World *world = TheWorldMgr->GetWorld(); if (world) { // If there's currently a world loaded, remove the movement from // the spectator camera. SpectatorCamera *camera = static_cast<GameWorld *>(world)->GetSpectatorCamera(); camera->SetSpectatorFlags(camera->GetSpectatorFlags() & ~movementFlag); } } BallController::BallController() : RigidBodyController(kControllerBall) { // This constructor is called when a new ball model is created. } BallController::BallController(const BallController& ballController) : RigidBodyController(ballController) { // This constructor is called when a ball controller is cloned. } BallController::~BallController() { } Controller *BallController::Replicate(void) const { return (new BallController(*this)); } bool BallController::ValidNode(const Node *node) { // This function is called by the engine to determine whether this // specific type of controller can be assigned to the particular // node passed in through the node parameter. This function should // return true if it can control the node, and otherwise it should // return false. In this case, the controller can only be applied // to model nodes. return (node->GetNodeType() == kNodeModel); } void BallController::PreprocessController(void) { // This function is called once before the target node is ever // rendered or moved. The base class PreprocessController() function // should always be called first, and then the subclass can do whatever // preprocessing it needs to do. In this case, we set a few of the // ball's physical parameters and give it a random initial velocity. RigidBodyController::PreprocessController(); SetRestitutionCoefficient(0.99F); SetSpinFrictionMultiplier(0.1F); SetRollingResistance(0.01F); SetLinearVelocity(Random::RandomUnitVector3D() * 2.0F); } RigidBodyStatus BallController::HandleNewRigidBodyContact(const RigidBodyContact *contact, RigidBodyController *contactBody) { // This function is called when the ball makes contact with another rigid body. // If we hit another ball, then we add a sound effect and some sparks to the world. if (contactBody->GetControllerType() == kControllerBall) { Node *node = GetTargetNode(); World *world = node->GetWorld(); Point3D position = node->GetWorldTransform() * contact->GetContactPosition(); OmniSource *source = new OmniSource("model/Ball", 40.0F); source->SetNodePosition(position); world->AddNewNode(source); SparkParticleSystem *sparks = new SparkParticleSystem(20); sparks->SetNodePosition(position); world->AddNewNode(sparks); } return (kRigidBodyUnchanged); } SparkParticleSystem::SparkParticleSystem(int32 count) : // Initialize the base class for line particles // and tell it where the particle pool is. LineParticleSystem(kParticleSystemSpark, &particlePool, "particle/Spark1"), // Initialize the particle pool by telling it where the array // of Particle structs is and how big it is. particlePool(kMaxParticleCount, particleArray) { // The SparkParticleSystem node creates a small burst of sparks // and then self-destructs when all of them have burned out. sparkCount = count; SetLengthMultiplier(4.0F); SetParticleSystemFlags(kParticleSystemSelfDestruct); } SparkParticleSystem::SparkParticleSystem() : LineParticleSystem(kParticleSystemSpark, &particlePool, "particle/Spark1"), particlePool(kMaxParticleCount, particleArray) { // This constructor gets used when the particle system is being loaded from // a saved game. In this case, we don't need to initialize anything. } SparkParticleSystem::~SparkParticleSystem() { } bool SparkParticleSystem::CalculateBoundingSphere(BoundingSphere *sphere) const { // Just return a sphere that's big enough to always enclose // all of the particles. This is in object-space coordinates. sphere->SetCenter(0.0F, 0.0F, 0.0F); sphere->SetRadius(20.0F); return (true); } void SparkParticleSystem::PreprocessNode(void) { // This function creates the spark particles. // Always call the base class PreprocessNode() function. LineParticleSystem::PreprocessNode(); // If there's already a particle in the system, then the node was loaded from // a saved game. We only create new particles if the particle system is empty. if (!GetFirstParticle()) { // Calculate the world-space center. Point3D center = GetSuperNode()->GetWorldTransform() * GetNodePosition(); const Vector2D *trig = Math::GetTrigTable(); int32 count = sparkCount; for (machine a = 0; a < count; a++) { // Grab a new unused particle from the pool. Particle *particle = particlePool.NewParticle(); if (!particle) { break; } particle->emitTime = 0; // Particle appears right away. particle->lifeTime = 500 + Random::RandomInteger(750); // Particle lives 500-1250 milliseconds. particle->radius = 0.02F; // The radius is 20 mm. particle->color.Set(1.0F, 1.0F, 0.1F, 1.0F); // It's yellow. particle->orientation = 0; // This doesn't matter for line particles. particle->position = center; // It starts at the effect's center. // Calculate a random velocity in a random direction. float speed = Random::RandomFloat(0.004F); const Vector2D& csp = trig[Random::RandomInteger(128)]; const Vector2D& cst = trig[Random::RandomInteger(256)]; particle->velocity.Set(cst.x * csp.y * speed, cst.y * csp.y * speed, csp.x * speed); // Add the particle to the particle system. AddParticle(particle); } } } void SparkParticleSystem::AnimateParticles(void) { // This function is called once per frame to move the particles. // Times are in milliseconds. int32 dt = TheTimeMgr->GetDeltaTime(); float fdt = TheTimeMgr->GetFloatDeltaTime(); Particle *particle = GetFirstParticle(); while (particle) { // Get the next particle here in case the current one is removed from the system. Particle *next = particle->nextParticle; int32 life = (particle->lifeTime -= dt); if (life > 0) { // Update velocity with gravity. particle->velocity.z += Const::gravity * fdt; // Move the particle and see if it hit the floor plane at z = 0. float z1 = particle->position.z - particle->radius; particle->position += particle->velocity * fdt; float z2 = particle->position.z - particle->radius; if (z1 * z2 <= 0.0F) { // The particle hit the floor, so reflect its velocity and remove some energy. particle->position.z = 0.05F - z2; particle->velocity.z *= -0.5F; } // If the particle is nearing the end of its life, fade it out. if (life < 100) { particle->color.alpha = (float) life * 0.01F; } } else { // Particle burned out. FreeParticle(particle); } particle = next; } } // The StartWindow constructor initializes the Window base class with the name of the panel // resource to load. The observer members are initialized with the functions that are // called when the "Start" and "Quit" push buttons in the window post activate events. StartWindow::StartWindow() : Window("panel/SimpleBall"), Global<StartWindow>(TheStartWindow), startButtonObserver(this, &StartWindow::HandleStartButtonEvent), quitButtonObserver(this, &StartWindow::HandleQuitButtonEvent) { } StartWindow::~StartWindow() { } void StartWindow::PreprocessWidget(void) { // We must call the Window base class PreprocessWidget() function first to initialize // the internal structures that are used to search for widgets. Window::PreprocessWidget(); // Assign observers to the push button widgets named "Start" and "Quit". Widget *button = FindWidget("Start"); button->SetObserver(&startButtonObserver); button = FindWidget("Quit"); button->SetObserver(&quitButtonObserver); } bool StartWindow::HandleKeyboardEvent(const KeyboardEventData *eventData) { if (eventData->eventType == kEventKeyDown) { if (eventData->keyCode == kKeyCodeEscape) { // The Escape key was pressed while this window had the focus. // If a world is loaded, then just delete the window and return to gameplay. if (TheWorldMgr->GetWorld()) { delete this; return (true); } } } return (false); } void StartWindow::HandleStartButtonEvent(Widget *widget, const WidgetEventData *eventData) { // This function is called whenever the "Start" push button posts an event. if (eventData->eventType == kEventWidgetActivate) { // If the widget was activated, then the user clicked the push button. // Delete the window and load a world to play. delete this; TheWorldMgr->LoadWorld("world/SimpleBall"); } } void StartWindow::HandleQuitButtonEvent(Widget *widget, const WidgetEventData *eventData) { // This function is called whenever the "Quit" push button posts an event. if (eventData->eventType == kEventWidgetActivate) { // If the widget was activated, then the user clicked the push button. // Quit the engine. TheEngine->Quit(); } } GameWorld::GameWorld(const char *name) : World(name), spectatorCamera(2.67F, 1.0F, 0.3F) { // This constructor is called when the Game::CreateWorld() function is // called to create a new world class. The world hasn't actually been loaded // from disk yet when we get here. } GameWorld::~GameWorld() { } const LocatorMarker *GameWorld::FindSpectatorLocator(const Zone *zone) { // Iterate through all of the markers in the zone. const Marker *marker = zone->GetFirstMarker(); while (marker) { if (marker->NodeEnabled()) { MarkerType type = marker->GetMarkerType(); if (type == kMarkerLocator) { const LocatorMarker *locator = static_cast<const LocatorMarker *>(marker); if (locator->GetLocatorType() == kLocatorSpectator) { return (locator); } } } // Get the next marker in the list. marker = marker->GetNextListElement(); } // Recursively look in all of the subzones. const Zone *subzone = zone->GetFirstSubzone(); while (subzone) { const LocatorMarker *locator = FindSpectatorLocator(subzone); if (locator) { return (locator); } subzone = subzone->ListElement<Zone>::GetNextListElement(); } return (nullptr); } WorldResult GameWorld::PreprocessWorld(void) { // The PreprocessWorld() function is called after the world has been constructed. // We must always call the base class PreprocessWorld() function first. If it // returns an error, then we just return the same result code. WorldResult result = World::PreprocessWorld(); if (result != kWorldOkay) { return (result); } // The world is now completely loaded. We search for a locator node that represents the // spectator camera's starting position. It has a locator type of kLocatorSpectator. const LocatorMarker *marker = FindSpectatorLocator(GetRootNode()); if (marker) { // A spectator marker was found. // Set the spectator camera's initial position and orientation. const Vector3D direction = marker->GetWorldTransform()[0]; float azimuth = Arctan(direction.y, direction.x); float altitude = Arctan(direction.z, Sqrt(direction.x * direction.x + direction.y * direction.y)); spectatorCamera.SetCameraAzimuth(azimuth); spectatorCamera.SetCameraAltitude(altitude); spectatorCamera.SetNodePosition(marker->GetWorldPosition()); } else { // A spectator marker was not found. // Put the spectator camera one meter above the origin by default. spectatorCamera.SetNodePosition(Point3D(0.0F, 0.0F, 1.0F)); } // Set the world's current camera to be our spectator camera. // The world will not render without a camera being set. SetWorldCamera(&spectatorCamera); return (kWorldOkay); } void GameWorld::RenderWorld(void) { // This function is called once per frame to render the world. // The subclass may do whatever it needs to before or after rendering, // but at some point must call World::RenderWorld(). World::RenderWorld(); } Game::Game() : // This is the constructor for the main application/game module class. // This class is created by the CreateApplication() function, which is // called right after the application/game DLL is loaded by the engine. // We initialize the global pointer to the current game instance first. Global<Game>(TheGame), // A model registration represents a model that can be instanced. // This particular declaration associates the kModelBall type with the // model named "model/Ball.mdl". The fourth parameter tells the engine // to precache the model resource, and the last parameter specifies // the default controller type to assign to models of type kModelBall. ballModelReg(kModelBall, "Bouncing Ball", "model/Ball", kModelPrecache, kControllerBall), // A controller registration tells the engine about an application-defined type of // controller and registers its name. In this case, the name "Bouncing Ball" will // appear in the list of available controllers in the World Editor for any node that // is determined to be a valid target node by the BallController::ValidNode() function. controllerReg(kControllerBall, "Bouncing Ball"), // A particle system registration tells the engine about an application-defined // type of particle system and registers its name. sparkParticleSystemReg(kParticleSystemSpark, "Sparks"), // Locator markers are registered so that the World Editor // can display their names in the Markers page. locatorReg(kLocatorSpectator, "Spectator Camera") { // This sets the function that is called when the user hits the // escape key during gameplay. We save the old function so that // it can be restored when the game DLL is unloaded. prevEscapeCallback = TheInputMgr->GetEscapeCallback(); prevEscapeCookie = TheInputMgr->GetEscapeCookie(); TheInputMgr->SetEscapeCallback(&EscapeCallback, this); // This registers our world class constructor with the World Manager. // We only need to do this if we have defined a subclass of the World // class that holds extra information. TheWorldMgr->SetWorldCreator(&CreateWorld); // These create the movement actions that are used to fly the spectator camera around. forwardAction = new MovementAction(kActionForward, kSpectatorMoveForward); backwardAction = new MovementAction(kActionBackward, kSpectatorMoveBackward); leftAction = new MovementAction(kActionLeft, kSpectatorMoveLeft); rightAction = new MovementAction(kActionRight, kSpectatorMoveRight); upAction = new MovementAction(kActionUp, kSpectatorMoveUp); downAction = new MovementAction(kActionDown, kSpectatorMoveDown); // These register our new actions with the Input Manager. TheInputMgr->AddAction(forwardAction); TheInputMgr->AddAction(backwardAction); TheInputMgr->AddAction(leftAction); TheInputMgr->AddAction(rightAction); TheInputMgr->AddAction(upAction); TheInputMgr->AddAction(downAction); // Let the Interface Manager determine when to change input devices to gameplay mode. TheInterfaceMgr->SetInputManagementMode(kInputManagementAutomatic); // Put the Message Manager in single-player mode. TheMessageMgr->BeginSinglePlayerGame(); // Create the start window and tell the Interface Manager to display it. TheInterfaceMgr->AddWidget(new StartWindow); } Game::~Game() { // When the game DLL is about to be unloaded, this destructor is called. TheWorldMgr->UnloadWorld(); TheWorldMgr->SetWorldCreator(nullptr); // If the start window exists, delete it. We need to do this here, instead of letting the // Interface Manager clean it up, because the destructor code for the window is in this DLL. delete TheStartWindow; // Tell the Message Manager to clean up. TheMessageMgr->EndGame(); delete downAction; delete upAction; delete rightAction; delete leftAction; delete backwardAction; delete forwardAction; // Restore the previous escape key handling function. TheInputMgr->SetEscapeCallback(prevEscapeCallback, prevEscapeCookie); } World *Game::CreateWorld(const char *name, void *cookie) { // This function is called when a new world is being loaded. It should // return a pointer to a newly constructed subclass of the World class. return (new GameWorld(name)); } void Game::EscapeCallback(void *cookie) { // This function is called when the user hits the escape key in gameplay // mode because we registered it using the InputMgr::SetEscapeCallback() function. // In this case, we open the start window shwoing the main menu. TheInterfaceMgr->AddWidget(new StartWindow); } </syntaxhighlight> == See Also == * [[Simple Games]] * [[SimpleChar Source Code]] [[Category:Tutorials]] b76e7b5d9b126d3fa747d1682b3fdd877a4f7139 SimpleChar Source Code 0 523 535 2023-09-12T21:43:45Z Eric Lengyel 1 Created page with "This page contains the complete source code for the <code>SimpleChar</code> example game module. See the [[Simple Games]] page for more information about the basic examples. == SimpleChar.h == <syntaxhighlight lang="c++"> #ifndef SimpleChar_h #define SimpleChar_h #include "C4Application.h" #include "C4World.h" #include "C4Input.h" #include "C4Cameras.h" #include "C4Interface.h" #include "C4Character.h" // Every application/game module needs to declare a function ca..." wikitext text/x-wiki This page contains the complete source code for the <code>SimpleChar</code> example game module. See the [[Simple Games]] page for more information about the basic examples. == SimpleChar.h == <syntaxhighlight lang="c++"> #ifndef SimpleChar_h #define SimpleChar_h #include "C4Application.h" #include "C4World.h" #include "C4Input.h" #include "C4Cameras.h" #include "C4Interface.h" #include "C4Character.h" // Every application/game module needs to declare a function called CreateApplication() // exactly as follows. (It must be declared extern "C", and it must include the tag // C4_MODULE_EXPORT.) The engine looks for this function in the DLL and calls // it to create an instance of the subclass of the Application class that the // application/game module defines. extern "C" { C4_MODULE_EXPORT C4::Application *CreateApplication(void); } namespace SimpleChar { using namespace C4; // These are action types used to define action bindings in the // Input Manager. If the four-character code for an action is // 'abcd', then any input control (there can be more than one) // bound to %abcd triggers the associated action. enum : ActionType { kActionForward = 'frwd', kActionBackward = 'bkwd', kActionLeft = 'left', kActionRight = 'rght', kActionUp = 'jump', kActionDown = 'down', kActionUse = 'fire' }; // These are movement flags used by the soldier controller. They are set or cleared // by the Engage() and Disengage() functions in the MovementAction class. enum : uint32 { kMovementForward = 1 << 0, kMovementBackward = 1 << 1, kMovementLeft = 1 << 2, kMovementRight = 1 << 3, kMovementUp = 1 << 4, kMovementDown = 1 << 5, kMovementPlanarMask = 15 }; // Model types are associated with a model resource using the ModelRegistration // class. Models are registered with the engine in the Game constructor. enum : ModelType { kModelSoldier = 'sold' }; // New controller types are registered with the engine in the Game constructor. enum : ControllerType { kControllerSoldier = 'sold' }; // New locator types are registered with the engine in the Game constructor. // The 'spwn' locator is used to specify where the player should be positioned // when a world is loaded. enum : LocatorType { kLocatorSpawn = 'spwn' }; class SoldierController; // An Action object represents an input action that can be triggered by some // input control, such as a key on the keyboard or a button on a gamepad. // The HandleEngage() and HandleDisengage() methods are called when the button // is pressed and released, respectively. Actions are registered with the Input // Manager when the Game class is constructed. class MovementAction : public Action { private: uint32 movementFlag; public: MovementAction(ActionType type, uint32 flag); ~MovementAction(); void HandleEngage(void) override; void HandleDisengage(void) override; }; class UseAction : public Action { public: UseAction(); ~UseAction(); void HandleEngage(void) override; void HandleDisengage(void) override; }; // The Interactor class is used to track player interactions with objects in the scene. class SoldierInteractor : public Interactor { private: SoldierController *soldierController; public: SoldierInteractor(SoldierController *controller); ~SoldierInteractor(); void HandleInteractionEvent(EventType type, Node *node, const InteractionProperty *property, const Point3D *position) override; }; // Controllers are used to control anything that moves in the world. // New types of controllers defined by the application/game module are // registered with the engine when the Game class is constructed. // // The SoldierController is used to animate the soldier. It uses the // built-in character controller as a base class so that the engine's // native physics can be used to move the character. class SoldierController final : public CharacterController { private: // These are motion states that are used to keep track // of which animation should be played. enum { kMotionNone, kMotionStand, kMotionForward, kMotionBackward }; // The movement flags tell how the user is trying to move the player. uint32 movementFlags; // The soldier motion keeps track of what animation is currently playing. int32 soldierMotion; // The azimuth and altitude represent the direction the player is looking // by using the mouse. float modelAzimuth; float modelAltitude; // The frame animator controls playback of an animation resource. FrameAnimator frameAnimator; // The previous center of mass stores the center point of the character on the // previous frame. This is used with the new center point to activate triggers. Point3D previousCenterOfMass; // We keep an interactor object here in the controller. SoldierInteractor soldierInteractor; SoldierController(const SoldierController& soldierController); Controller *Replicate(void) const override; void SetSoldierMotion(int32 motion); public: SoldierController(float azimuth); ~SoldierController(); Model *GetTargetNode(void) const { return (static_cast<Model *>(Controller::GetTargetNode())); } uint32 GetMovementFlags(void) const { return (movementFlags); } void SetMovementFlags(uint32 flags) { movementFlags = flags; } float GetModelAzimuth(void) const { return (modelAzimuth); } float GetModelAltitude(void) const { return (modelAltitude); } SoldierInteractor *GetSoldierInteractor(void) { return (&soldierInteractor); } void PreprocessController(void) override; void MoveController(void) override; }; // The ChaseCamera class represents a camera that will track the player's movement. class ChaseCamera : public FrustumCamera { private: Model *targetModel; public: ChaseCamera(); ~ChaseCamera(); Model *GetTargetModel(void) const { return (targetModel); } void SetTargetModel(Model *model) { targetModel = model; } void MoveCamera(void) override; }; // The application/game module will usually define a subclass of the World // class so that extra information can be associated with the current world. // In this case, a pointer to a spawn locator and an instance of the ChaseCamera // class is included with the world. A new instance of this World subclass should // be returned when the Game::CreateWorld() function is called (see below). class GameWorld : public World { private: const LocatorMarker *spawnLocator; ChaseCamera chaseCamera; static const LocatorMarker *FindSpawnLocator(const Zone *zone); public: GameWorld(const char *name); ~GameWorld(); const LocatorMarker *GetSpawnLocator(void) const { return (spawnLocator); } ChaseCamera *GetChaseCamera(void) { return (&chaseCamera); } ResourceResult PreprocessWorld(void) override; void HandlePhysicsSpaceExit(RigidBodyController *rigidBody) override; void DetectInteractions(void) override; void RenderWorld(void) override; }; // Every application/game module needs to define a subclass of the Application // class to serve as the primary interface with the engine. This subclass is // created and returned to the engine in the CreateApplication() function. // There should be only one instance of this class, and a pointer to it is // declared below. class Game : public Application, public Global<Game> { private: ModelRegistration soldierModelReg; LocatorRegistration locatorReg; InputMgr::KeyCallback *prevEscapeCallback; void *prevEscapeCookie; MovementAction *forwardAction; MovementAction *backwardAction; MovementAction *leftAction; MovementAction *rightAction; MovementAction *upAction; MovementAction *downAction; UseAction *useAction; SoldierController *soldierController; static World *CreateWorld(const char *name, void *cookie); static void EscapeCallback(void *cookie); public: Game(); ~Game(); SoldierController *GetSoldierController(void) const { return (soldierController); } EngineResult LoadWorld(const char *name) override; void UnloadWorld(void) override; }; // This is a pointer to the one instance of the Game class through which // any other part of the application/game module can access it. extern Game *TheGame; } #endif </syntaxhighlight> == SimpleChar.cpp == <syntaxhighlight lang="c++"> #include "SimpleChar.h" using namespace SimpleChar; // This is the definition of the pointer to the Game class global. // It should be initialized to nullptr, and its value will be set by // the Game class constructor. Game *SimpleChar::TheGame = nullptr; C4::Application *CreateApplication(void) { // This function should simply return a pointer to a new instance of // the Application class. Normally, the application/game module will // define a subclass of the Application class (in this case, the // Game class) and return a pointer to a new instance of that type. // This function is called exactly one time right after the // application/game module DLL is loaded by the engine. The returned // class is destroyed via the virtual destructor of the Application // class right before the application/game module DLL is unloaded. return (new Game); } MovementAction::MovementAction(ActionType type, uint32 flag) : Action(type) { // Each instance of the MovementAction class represents a movement // in a single direction, as indicated by the flag parameter. // All of the MovementAction instances are constructed in the // Game class constructor. movementFlag = flag; } MovementAction::~MovementAction() { } void MovementAction::HandleEngage(void) { // This function is called when the input control associated with this // particular action is engaged (e.g., a key was pressed). We respond to // such an event by setting a movement flag in the soldier controller. SoldierController *controller = TheGame->GetSoldierController(); if (controller) { controller->SetMovementFlags(controller->GetMovementFlags() | movementFlag); } } void MovementAction::HandleDisengage(void) { // This function is called when the input control associated with this // particular action is disengaged (e.g., a key was released). We respond to // such an event by clearing a movement flag in the soldier controller. SoldierController *controller = TheGame->GetSoldierController(); if (controller) { controller->SetMovementFlags(controller->GetMovementFlags() & ~movementFlag); } } UseAction::UseAction() : Action(kActionUse) { } UseAction::~UseAction() { } void UseAction::HandleEngage(void) { // The player has pressed the fire/use button. If we are currently interacting with // a node in the scene and that node has a controller, then we send an activate event // to that controller to let it know that the player is doing something with it. SoldierController *controller = TheGame->GetSoldierController(); if (controller) { const SoldierInteractor *interactor = controller->GetSoldierInteractor(); const Node *interactionNode = interactor->GetInteractionNode(); if (interactionNode) { Controller *interactionController = interactionNode->GetController(); if (interactionController) { interactionController->HandleInteractionEvent(kEventInteractionActivate, &interactor->GetInteractionPosition(), controller->GetTargetNode()); } } } } void UseAction::HandleDisengage(void) { // The player has released the fire/use button. Let the node with which we are interacting // know that we are done with it by sending its controller a deactivate event. SoldierController *controller = TheGame->GetSoldierController(); if (controller) { const SoldierInteractor *interactor = controller->GetSoldierInteractor(); const Node *interactionNode = interactor->GetInteractionNode(); if (interactionNode) { Controller *interactionController = interactionNode->GetController(); if (interactionController) { interactionController->HandleInteractionEvent(kEventInteractionDeactivate, &interactor->GetInteractionPosition(), controller->GetTargetNode()); } } } } SoldierInteractor::SoldierInteractor(SoldierController *controller) { soldierController = controller; } SoldierInteractor::~SoldierInteractor() { } void SoldierInteractor::HandleInteractionEvent(EventType type, Node *node, const InteractionProperty *property, const Point3D *position) { // Always call the base class counterpart. Interactor::HandleInteractionEvent(type, node, property, position); // If the node with which we are interacting has a controller, // then pass the event through to that controller. Controller *controller = node->GetController(); if (controller) { controller->HandleInteractionEvent(type, position); } } SoldierController::SoldierController(float azimuth) : CharacterController(kControllerSoldier), soldierInteractor(this) { soldierMotion = kMotionNone; movementFlags = 0; modelAzimuth = azimuth; modelAltitude = 0.0F; } SoldierController::SoldierController(const SoldierController& soldierController) : CharacterController(soldierController), soldierInteractor(this) { soldierMotion = kMotionNone; movementFlags = 0; modelAzimuth = 0.0F; modelAltitude = 0.0F; } SoldierController::~SoldierController() { } Controller *SoldierController::Replicate(void) const { return (new SoldierController(*this)); } void SoldierController::PreprocessController(void) { // This function is called once before the target node is ever // rendered or moved. The base class PreprocessController() function // should always be called first, and then the subclass can do whatever // preprocessing it needs to do. CharacterController::PreprocessController(); SetRigidBodyFlags(kRigidBodyKeepAwake | kRigidBodyFixedOrientation); SetFrictionCoefficient(0.0F); // We use a frame animator to play animation resources // for the soldier model. Model *soldier = GetTargetNode(); frameAnimator.SetTargetModel(soldier); soldier->SetRootAnimator(&frameAnimator); // Initialize the previous center of mass to the current center of mass // so that this doesn't contain garbage the first time we call ActivateTriggers(). previousCenterOfMass = GetWorldCenterOfMass(); // Register our interactor with the world. soldier->GetWorld()->AddInteractor(&soldierInteractor); } void SoldierController::MoveController(void) { // This function is called once per frame to allow the controller to // move its target node. // The movementIndexTable is a 16-entry table that maps all combinations of // the forward, backward, left, and right movement flags to one of eight directions. // The direction codes are as follows: // // 0 - forward // 1 - backward // 2 - left // 3 - right // 4 - forward and left // 5 - forward and right // 6 - backward and left // 7 - backward and right // // The number 8 in the table means no movement, and it appears where either no // movement buttons are being pressed or two opposing buttons are the only ones pressed // (e.g., left and right pressed simultaneously cancel each other out). static const uint8 movementIndexTable[16] = { 8, 0, 1, 8, 2, 4, 6, 2, 3, 5, 7, 3, 8, 0, 1, 8 }; // First, we grab the mouse deltas from the Input Manager. // We use these to change the angles representing the direction in // which the player is looking/moving. float azm = modelAzimuth + TheInputMgr->GetMouseDeltaX(); if (azm < -Math::tau_over_2) { azm += Math::tau; } else if (azm > Math::tau_over_2) { azm -= Math::tau; } float alt = Clamp(modelAltitude + TheInputMgr->GetMouseDeltaY(), -1.45F, 1.45F); modelAzimuth = azm; modelAltitude = alt; // Now, we determine whether the player is attempting to move, and // we play the appropriate animation on the soldier model. int32 motion = kMotionStand; Vector2D propel(0.0F, 0.0F); int32 index = movementIndexTable[movementFlags & kMovementPlanarMask]; if (index < 8) { // The movementDirectionTable maps each direction code looked up in the // movementIndexTable to an angle measured counterclockwise from the straight // ahead direction in units of tau/8. static const float movementDirectionTable[8] = { 0.0F, 4.0F, 2.0F, -2.0F, 1.0F, -1.0F, 3.0F, -3.0F }; float direction = movementDirectionTable[index] * Math::tau_over_8 + modelAzimuth; // Set the propulsive force based on the direction of movement. Vector2D cs = CosSin(direction); propel.Set(cs.x * 100.0F, cs.y * 100.0F); // Determine whether we should play the forward or backward running animation. motion = ((index == 1) || (index >= 6)) ? kMotionBackward : kMotionForward; } // Update the external force for the rigid body representing the character. // The GetGroundContact() function is a member of the CharacterController base class. if (GetGroundContact()) { SetExternalLinearResistance(Vector2D(10.0F, 10.0F)); SetExternalForce(propel); } else { // If the soldier is not on the ground, reduce the propulsive force down to 2%. // This controls how well the player is able to control his movement while // falling through the air. SetExternalLinearResistance(Vector2D::zero); SetExternalForce(propel * 0.02F); } // Change the soldier's orientation based on horizontal mouse movement. // The SetCharacterOrientation() function is a member of the CharacterController base class. SetCharacterOrientation(modelAzimuth); // If the animation needs to be changed, do it. if (motion != soldierMotion) { SetSoldierMotion(motion); } // Activate triggers along the line connecting to the current center of mass // from the center of mass in the previous frame. Model *model = GetTargetNode(); model->GetWorld()->ActivateTriggers(previousCenterOfMass, GetWorldCenterOfMass(), 0.25F, model); previousCenterOfMass = GetWorldCenterOfMass(); // Call the Model::AnimateModel() function to update the animation playing for the model. GetTargetNode()->AnimateModel(); } void SoldierController::SetSoldierMotion(int32 motion) { // This function sets the animation resource corresponding to // the current type of motion assigned to the soldier. Interpolator *interpolator = frameAnimator.GetFrameInterpolator(); if (motion == kMotionStand) { frameAnimator.SetAnimation("soldier/Stand"); interpolator->SetMode(kInterpolatorForward | kInterpolatorLoop); } else if (motion == kMotionForward) { frameAnimator.SetAnimation("soldier/Run"); interpolator->SetMode(kInterpolatorForward | kInterpolatorLoop); } else if (motion == kMotionBackward) { frameAnimator.SetAnimation("soldier/Backward"); interpolator->SetMode(kInterpolatorForward | kInterpolatorLoop); } soldierMotion = motion; } ChaseCamera::ChaseCamera() : FrustumCamera(2.67F, 1.0F) { targetModel = nullptr; } ChaseCamera::~ChaseCamera() { } void ChaseCamera::MoveCamera(void) { Model *model = GetTargetModel(); if (model) { CollisionData data; SoldierController *controller = static_cast<SoldierController *>(model->GetController()); // Here, we calculate the local coordinate frame for the chase camera // based on the direction that the player is looking. Vector2D t = CosSin(controller->GetModelAzimuth()); Vector2D u = CosSin(controller->GetModelAltitude()); Vector3D view(t.x * u.x, t.y * u.x, u.y); Vector3D right(t.y, -t.x, 0.0F); Vector3D down = Cross(view, right); // We are going to place the camera behind the player, but we don't // want the camera to go through any geometry, so we'll do a quick // check for a collision. const Point3D& position = model->GetWorldPosition(); Point3D p1(position.x, position.y, position.z + 1.5F); Point3D p2 = p1 - view * 4.0F; if (GetWorld()->DetectCollision(p1, p2, 0.3F, kCollisionCamera, &data)) { // There's something in the way, so move the camera in closer // to the player. float s = data.param; p2 = p1 * (1.0F - s) + p2 * s; } // Set the camera's position and orientation. SetNodeTransform(right, down, view, p2); } } GameWorld::GameWorld(const char *name) : World(name) { // This constructor is called when the Game::CreateWorld() function is // called to create a new world class. The world hasn't actually been loaded // from disk yet when we get here. spawnLocator = nullptr; } GameWorld::~GameWorld() { } const LocatorMarker *GameWorld::FindSpawnLocator(const Zone *zone) { // Iterate through all of the markers in the zone. const Marker *marker = zone->GetFirstMarker(); while (marker) { if (marker->NodeEnabled()) { MarkerType type = marker->GetMarkerType(); if (type == kMarkerLocator) { const LocatorMarker *locator = static_cast<const LocatorMarker *>(marker); if (locator->GetLocatorType() == kLocatorSpawn) { return (locator); } } } // Get the next marker in the list. marker = marker->GetNextListElement(); } // Look in all of the subzones. const Zone *subzone = zone->GetFirstSubzone(); while (subzone) { const LocatorMarker *locator = FindSpawnLocator(subzone); if (locator) { return (locator); } subzone = subzone->ListElement<Zone>::GetNextListElement(); } return (nullptr); } WorldResult GameWorld::PreprocessWorld(void) { // The PreprocessWorld() function is called after the world has been constructed. // We must always call the base class PreprocessWorld() function first. If it // returns an error, then we just return the same result code. WorldResult result = World::PreprocessWorld(); if (result != kWorldOkay) { return (result); } // The world is now completely loaded. We search for a locator node that represents the // player's spawn position. It has a locator type of kLocatorSpawn. spawnLocator = FindSpawnLocator(GetRootNode()); return (kWorldOkay); } void GameWorld::HandlePhysicsSpaceExit(RigidBodyController *rigidBody) { // Do nothing because this code can't handle it. } void GameWorld::DetectInteractions(void) { // The DetectInteractions() function is called once per frame. Before calling the base // class's DetectInteractions() function, we set up the interaction probe to be a line // segment extending two meters from the players head in the direction that the // camera is looking. SoldierController *controller = TheGame->GetSoldierController(); if (controller) { const Point3D& p = controller->GetTargetNode()->GetWorldPosition(); Point3D position(p.x, p.y, p.z + 1.5F); const Vector3D& direction = chaseCamera.GetWorldTransform()[2]; controller->GetSoldierInteractor()->SetInteractionProbe(position, position + direction * 2.0F); } // Always call the base class counterpart. World::DetectInteractions(); } void GameWorld::RenderWorld(void) { // This function is called once per frame to render the world. // The subclass may do whatever it needs to before or after rendering, // but at some point must call World::RenderWorld(). World::RenderWorld(); } Game::Game() : // This is the constructor for the main application/game module class. // This class is created by the CreateApplication() function, which is // called right after the application/game DLL is loaded by the engine. // We initialize the global pointer to the current game instance first. Global<Game>(TheGame), // A model registration represents a model that can be instanced. // This particular declaration associates the kModelSoldier type with the // model named "soldier/Soldier.mdl". The fourth parameter tells the engine // to precache the model resource and not to display the model in the // World Editor. The last parameter specifies the default controller // type to assign to models of type kModelSoldier. soldierModelReg(kModelSoldier, nullptr, "soldier/Soldier", kModelPrecache | kModelPrivate, kControllerSoldier), // Locator markers are registered so that the World Editor // can display their names in the Markers page. locatorReg(kLocatorSpawn, "Spawn Location") { // This sets the function that is called when the user hits the // escape key during gameplay. We save the old function so that // it can be restored when the game DLL is unloaded. prevEscapeCallback = TheInputMgr->GetEscapeCallback(); prevEscapeCookie = TheInputMgr->GetEscapeCookie(); TheInputMgr->SetEscapeCallback(&EscapeCallback, this); // This registers our world class constructor with the World Manager. // We only need to do this if we have defined a subclass of the World // class that holds extra information. TheWorldMgr->SetWorldCreator(&CreateWorld); // These create the movement actions that are used to // move the player around and interact with objects. forwardAction = new MovementAction(kActionForward, kMovementForward); backwardAction = new MovementAction(kActionBackward, kMovementBackward); leftAction = new MovementAction(kActionLeft, kMovementLeft); rightAction = new MovementAction(kActionRight, kMovementRight); upAction = new MovementAction(kActionUp, kMovementUp); downAction = new MovementAction(kActionDown, kMovementDown); useAction = new UseAction; // These register our new actions with the Input Manager. TheInputMgr->AddAction(forwardAction); TheInputMgr->AddAction(backwardAction); TheInputMgr->AddAction(leftAction); TheInputMgr->AddAction(rightAction); TheInputMgr->AddAction(upAction); TheInputMgr->AddAction(downAction); TheInputMgr->AddAction(useAction); // Let the Interface Manager determine when to change input devices to gameplay mode. TheInterfaceMgr->SetInputManagementMode(kInputManagementAutomatic); soldierController = nullptr; } Game::~Game() { // When the game DLL is about to be unloaded, this destructor is called. TheWorldMgr->UnloadWorld(); TheWorldMgr->SetWorldCreator(nullptr); delete useAction; delete downAction; delete upAction; delete rightAction; delete leftAction; delete backwardAction; delete forwardAction; // Restore the previous escape key handling function. TheInputMgr->SetEscapeCallback(prevEscapeCallback, prevEscapeCookie); } World *Game::CreateWorld(const char *name, void *cookie) { // This function is called when a new world is being loaded. It should // return a pointer to a newly constructed subclass of the World class. return (new GameWorld(name)); } void Game::EscapeCallback(void *cookie) { // This function is called when the user hits the escape key in gameplay // mode because we registered it using the InputMgr::SetEscapeCallback() function. } EngineResult Game::LoadWorld(const char *name) { // Attempt to load the world. WorldResult result = TheWorldMgr->LoadWorld(name); if (result == kWorldOkay) { GameWorld *world = static_cast<GameWorld *>(TheWorldMgr->GetWorld()); const LocatorMarker *locator = world->GetSpawnLocator(); if (locator) { // If a spawn locator was found in the world, put a soldier character there. // The BeginSinglePlayerGame() function puts the Message Manager in single player mode. TheMessageMgr->BeginSinglePlayerGame(); // Calculate the angle corresponding to the direction the character is initially facing. const Vector3D direction = locator->GetWorldTransform()[0]; float azimuth = Arctan(direction.y, direction.x); // Load a soldier model and attach a controller to it. Model *model = Model::GetModel(kModelSoldier); SoldierController *controller = new SoldierController(azimuth); model->SetController(controller); TheGame->soldierController = controller; // Put the model in the world at the locator's position. model->SetNodePosition(locator->GetWorldPosition()); locator->GetWorld()->AddNewNode(model); // Set the world's current camera to be our chase camera. // The world will not render without a camera being set. ChaseCamera *camera = world->GetChaseCamera(); camera->SetTargetModel(model); world->SetWorldCamera(camera); } } return (result); } void Game::UnloadWorld(void) { TheWorldMgr->UnloadWorld(); TheMessageMgr->EndGame(); TheGame->soldierController = nullptr; } </syntaxhighlight> == See Also == * [[Simple Games]] * [[SimpleBall Source Code]] [[Category:Tutorials]] b07e93cffc036dbdd334310eea63cb38c6cc708b Release Notes for Version 7.2 0 524 536 2023-09-16T22:08:21Z Eric Lengyel 1 Created page with "__NOTOC__ '''Release date:''' TBD == Core Engine == === Graphics Manager === * Horizon mapping is now disabled by default for spot lights. It can be enabled by checking the "Include spot lights" box in the [[Material Manager]] or in the settings for the Horizon process. * A problem in which the perspective mask would not be updated for effect nodes in the [[World Editor]] has been fixed. === Interface Manager === * Some minor updates have been made in the Slug Libr..." wikitext text/x-wiki __NOTOC__ '''Release date:''' TBD == Core Engine == === Graphics Manager === * Horizon mapping is now disabled by default for spot lights. It can be enabled by checking the "Include spot lights" box in the [[Material Manager]] or in the settings for the Horizon process. * A problem in which the perspective mask would not be updated for effect nodes in the [[World Editor]] has been fixed. === Interface Manager === * Some minor updates have been made in the Slug Library. === Math Library === * The math library has been updated to be consistent with conventions used in the upcoming book ''Projective Geometric Algebra Illuminated''. * The <code>Transform4D</code> class has been renamed to <code>Transform3D</code>. In general, the 3D suffix is used whenever something operates on 3D space, so even though the <code>Transform3D</code> class is a special form of 4&nbsp;&times;&nbsp;4 matrix, it still has the 3D suffix. == In Progress == There are several new features that are in progress as of this release: * The engine is transitioning from OpenGL to Vulkan. Some code is present in version 7.2, but it is not complete. * A new physically-based metallic material attribute is in progress. * A new fur shader is in progress. * The way that terrain is textured is being updated. 1f64b59ce23aeb9302183895082eb93e12669326 537 536 2023-09-16T22:08:38Z Eric Lengyel 1 wikitext text/x-wiki __NOTOC__ '''Release date:''' TBD == Core Engine == === Graphics Manager === * Horizon mapping is now disabled by default for spot lights. It can be enabled by checking the "Include spot lights" box in the [[Material Editor]] or in the settings for the Horizon process. * A problem in which the perspective mask would not be updated for effect nodes in the [[World Editor]] has been fixed. === Interface Manager === * Some minor updates have been made in the Slug Library. === Math Library === * The math library has been updated to be consistent with conventions used in the upcoming book ''Projective Geometric Algebra Illuminated''. * The <code>Transform4D</code> class has been renamed to <code>Transform3D</code>. In general, the 3D suffix is used whenever something operates on 3D space, so even though the <code>Transform3D</code> class is a special form of 4&nbsp;&times;&nbsp;4 matrix, it still has the 3D suffix. == In Progress == There are several new features that are in progress as of this release: * The engine is transitioning from OpenGL to Vulkan. Some code is present in version 7.2, but it is not complete. * A new physically-based metallic material attribute is in progress. * A new fur shader is in progress. * The way that terrain is textured is being updated. fc7057a5aceb4223c18844c61d1e8f7d43fceaaf 538 537 2023-09-24T04:50:20Z Eric Lengyel 1 wikitext text/x-wiki __NOTOC__ '''Release date:''' TBD == Core Engine == === Graphics Manager === * Horizon mapping is now disabled by default for spot lights. It can be enabled by checking the "Include spot lights" box in the [[Material Editor]] or in the settings for the Horizon process. * A problem in which the perspective mask would not be updated for effect nodes in the [[World Editor]] has been fixed. === Interface Manager === * Some minor updates have been made in the Slug Library. === Math Library === * The math library has been updated to be consistent with conventions used in the upcoming book ''Projective Geometric Algebra Illuminated''. * The <code>Transform4D</code> class has been renamed to <code>Transform3D</code>. In general, the 3D suffix is used whenever something operates on 3D space, so even though the <code>Transform3D</code> class is a special form of 4&nbsp;&times;&nbsp;4 matrix, it still has the 3D suffix. * The <code>Rect</code> class has been renamed to <code>Rect2D</code> to be consistent with the naming of similar types of objects. == In Progress == There are several new features that are in progress as of this release: * The engine is transitioning from OpenGL to Vulkan. Some code is present in version 7.2, but it is not complete. * A new physically-based metallic material attribute is in progress. * A new fur shader is in progress. * The way that terrain is textured is being updated. 42b4b682ba1fcdb9aa963af7d48673ffa92fd6ff 543 538 2024-05-17T23:02:58Z Eric Lengyel 1 wikitext text/x-wiki __NOTOC__ '''Release date:''' TBD == Core Engine == === Graphics Manager === * Horizon mapping is now disabled by default for spot lights. It can be enabled by checking the "Include spot lights" box in the [[Material Editor]] or in the settings for the Horizon process. * A problem in which the perspective mask would not be updated for effect nodes in the [[World Editor]] has been fixed. === Interface Manager === * The Slug Library has been updated to version 7.1. === Math Library === * The math library has been updated to be consistent with conventions used in the new book [https://www.amazon.com/dp/B0CXY8C72T/?tag=terathon-20 ''Projective Geometric Algebra Illuminated'']. * The <code>Transform4D</code> class has been renamed to <code>Transform3D</code>. In general, the 3D suffix is used whenever something operates on 3D space, so even though the <code>Transform3D</code> class is a special form of 4&nbsp;&times;&nbsp;4 matrix, it still has the 3D suffix. * The <code>Rect</code> class has been renamed to <code>Rect2D</code> to be consistent with the naming of similar types of objects. == World Editor == * The Merge Geometries command now accounts for various geometry settings that were previously reset to defaults. The detail ring, detail level bias, and collision level settings in the merged geometry become the minimum values among the input geometries. == In Progress == There are several new features that are in progress as of this release: * The engine is transitioning from OpenGL to Vulkan. Some code is present in version 7.2, but it is not complete. * A new physically-based metallic material attribute is in progress. * A new fur shader is in progress. * The way that terrain is textured is being updated. f161765f90611faa545aec5262d5cb40d7ef91f4 544 543 2024-07-02T07:26:46Z Eric Lengyel 1 wikitext text/x-wiki __NOTOC__ '''Release date:''' TBD == Core Engine == === Graphics Manager === * Tone mapping has been redone from scratch and now produces better results. * Horizon mapping is now disabled by default for spot lights. It can be enabled by checking the "Include spot lights" box in the [[Material Editor]] or in the settings for the Horizon process. * A problem in which the perspective mask would not be updated for effect nodes in the [[World Editor]] has been fixed. * Counterexposure can now be turned on or off for fog spaces. The default is off. You would typical want to turn this on when a fog space is visible across environments of highly variable illuminance so that increased exposure in the darker areas don't make the fog really bright. === Interface Manager === * The Slug Library has been updated to version 7.1. === Math Library === * The math library has been updated to be consistent with conventions used in the new book [https://www.amazon.com/dp/B0CXY8C72T/?tag=terathon-20 ''Projective Geometric Algebra Illuminated'']. * The <code>Transform4D</code> class has been renamed to <code>Transform3D</code>. In general, the 3D suffix is used whenever something operates on 3D space, so even though the <code>Transform3D</code> class is a special form of 4&nbsp;&times;&nbsp;4 matrix, it still has the 3D suffix. * The <code>Rect</code> class has been renamed to <code>Rect2D</code> to be consistent with the naming of similar types of objects. == World Editor == * The Merge Geometries command now accounts for various geometry settings that were previously reset to defaults. The detail ring, detail level bias, and collision level settings in the merged geometry become the minimum values among the input geometries. == In Progress == There are several new features that are in progress as of this release: * The engine is transitioning from OpenGL to Vulkan. Some code is present in version 7.2, but it is not complete. * A new physically-based metallic material attribute is in progress. * A new fur shader is in progress. * The way that terrain is textured is being updated. 113ce1f69d811e0e99df9614f27dcce51de83ffd 546 544 2024-09-03T23:08:09Z Eric Lengyel 1 wikitext text/x-wiki __NOTOC__ '''Release date:''' TBD == Core Engine == === Graphics Manager === * Tone mapping has been redone from scratch and now produces better results. A new utility window shows the histogram analysis in real time, and it can be opened by typing <code>tone</code> in the command console. * Horizon mapping is now disabled by default for spot lights. It can be enabled by checking the "Include spot lights" box in the [[Material Editor]] or in the settings for the Horizon process. * A problem in which the perspective mask would not be updated for effect nodes in the [[World Editor]] has been fixed. * Counterexposure can now be turned on or off for fog spaces. The default is off. You would typical want to turn this on when a fog space is visible across environments of highly variable illuminance so that increased exposure in the darker areas don't make the fog really bright. === Interface Manager === * The Slug Library has been updated to version 7.2. === Math Library === * The math library has been updated to be consistent with conventions used in the new book [https://www.amazon.com/dp/B0CXY8C72T/?tag=terathon-20 ''Projective Geometric Algebra Illuminated'']. * The <code>Transform4D</code> class has been renamed to <code>Transform3D</code>. In general, the 3D suffix is used whenever something operates on 3D space, so even though the <code>Transform3D</code> class is a special form of 4&nbsp;&times;&nbsp;4 matrix, it still has the 3D suffix. * The <code>Rect</code> class has been renamed to <code>Rect2D</code> to be consistent with the naming of similar types of objects. === Miscellaneous === * The resource packer can now create pack files that are larger than 4 GB in size. == World Editor == * The Merge Geometries command now accounts for various geometry settings that were previously reset to defaults. The detail ring, detail level bias, and collision level settings in the merged geometry become the minimum values among the input geometries. == In Progress == There are several new features that are in progress as of this release: * The engine is transitioning from OpenGL to Vulkan. Some code is present in version 7.2, but it is not complete. * A new physically-based metallic material attribute is in progress. * A new fur shader is in progress. * The way that terrain is textured is being updated. d467e2d637d345acad7a01200014101652795e5d 547 546 2024-09-03T23:08:21Z Eric Lengyel 1 wikitext text/x-wiki __NOTOC__ '''Release date:''' September 3, 2024 == Core Engine == === Graphics Manager === * Tone mapping has been redone from scratch and now produces better results. A new utility window shows the histogram analysis in real time, and it can be opened by typing <code>tone</code> in the command console. * Horizon mapping is now disabled by default for spot lights. It can be enabled by checking the "Include spot lights" box in the [[Material Editor]] or in the settings for the Horizon process. * A problem in which the perspective mask would not be updated for effect nodes in the [[World Editor]] has been fixed. * Counterexposure can now be turned on or off for fog spaces. The default is off. You would typical want to turn this on when a fog space is visible across environments of highly variable illuminance so that increased exposure in the darker areas don't make the fog really bright. === Interface Manager === * The Slug Library has been updated to version 7.2. === Math Library === * The math library has been updated to be consistent with conventions used in the new book [https://www.amazon.com/dp/B0CXY8C72T/?tag=terathon-20 ''Projective Geometric Algebra Illuminated'']. * The <code>Transform4D</code> class has been renamed to <code>Transform3D</code>. In general, the 3D suffix is used whenever something operates on 3D space, so even though the <code>Transform3D</code> class is a special form of 4&nbsp;&times;&nbsp;4 matrix, it still has the 3D suffix. * The <code>Rect</code> class has been renamed to <code>Rect2D</code> to be consistent with the naming of similar types of objects. === Miscellaneous === * The resource packer can now create pack files that are larger than 4 GB in size. == World Editor == * The Merge Geometries command now accounts for various geometry settings that were previously reset to defaults. The detail ring, detail level bias, and collision level settings in the merged geometry become the minimum values among the input geometries. == In Progress == There are several new features that are in progress as of this release: * The engine is transitioning from OpenGL to Vulkan. Some code is present in version 7.2, but it is not complete. * A new physically-based metallic material attribute is in progress. * A new fur shader is in progress. * The way that terrain is textured is being updated. b77d5715a483bdbc1486af340d5522552a3a854b Panel Editor 0 437 539 440 2023-11-08T21:14:29Z Eric Lengyel 1 wikitext text/x-wiki [[File:Paneleditor.png|right|frame|'''Figure 1.''' The Panel Editor window.]] The '''Panel Editor''', shown in the image to the right, is a tool included with the C4 Engine that is used to create and edit graphical user interfaces of two different types. First, the panel editor can be used to create windows, dialogs, and heads-up displays that are rendered on top of a game on a two-dimensional desktop, and these interfaces are saved in individual panel resource files. Second, the panel editor can be used to create interactive in-game interface panels that are saved as part of the world in which they exist. An interface panel is composed of a set of widgets, and many different types of widgets, including simple text and image widgets and more complex widgets like list boxes, are built into the engine. Custom widget subclasses can be defined in the game code and registered with the engine so they appear in the Panel Editor. Each widget can have one or more ''[[sprockets]]'' attached to it that produce animations of various kinds. Widgets belonging to in-game interface panels can also have scripts attached to them that get executed when the user interacts with the widgets. == Creating and Editing Panels == === Desktop Panel Resources === New panel resources can be created, and existing panel resources can be edited, by choosing the New Panel or Open Panel commands in the [[C4 Menu]]. The <code>panel</code> command can also be entered in the [[Command Console]] to open an existing panel resource. The dimensions, window title, and various flags for a desktop user interface panel are set by choosing Window Settings from the Panel menu. After saving the panel, the created <code>.pan</code> file can then be used in your game with the [http://c4engine.com/docs/InterfaceMgr/Window.html Window] class. === In-Game Panel Effects === An interface panel can be created in the World Editor by using the Panel Effect tool in the [[Effects Page]]. When a panel effect is selected, the Panel Editor can be opened for it by choosing &ldquo;Edit Script or Panel&rdquo; from the Node menu, which has the shortcut Ctrl-E. The Panel Editor is also accessible from the Controller pane in the Node Info window. The Panel Effect tool draws a rectangular region representing the boundary of the panel. When a panel is first created, it automatically has a Panel Controller assigned to it that can be accessed under the Controller pane in the Node Info window. An in-game panel possesses both its physical size in the world, as drawn with the Panel Effect tool, and an internal interface resolution. The resolution is adjusted in the properties for the Panel Controller. The interface resolution determines how big the virtual screen is on which items will be placed with the Panel Editor. Whatever resolution is chosen, the entire panel is fit precisely into the physical dimensions determined by the rectangle drawn in the World Editor. Thus, it's usually desirable to match the aspect ratios of both the panel's physical size and its interface resolution to avoid stretching the contents of the panel. Under the '''Panel''' tab in the Node Info window, there are three check boxes that affect how the panel is rendered. * The '''Apply depth offset''' flag causes the panel to be rendered with a small depth offset forward. This avoids z-fighting artifacts that could otherwise appear if a panel was drawn in the same plane as background geometry. * The '''Render two-sided''' flag causes the panel to be rendered regardless of on which side of the panel's plane the camera currently is. This lets the panel be seen from the back if it's drawn on a transparent surface or floating in mid-air. * The '''Render with fog''' flag allows fog to be rendered over a panel. This must be explicitly enabled in order for a panel to be rendered in a fogged environment. A panel effect can be made interactive by assigning the Interaction property to it under the Properties pane of the Node Info window. An interactive panel can display a cursor on top of the panel while the user is engaged with it. The cursor's texture image is specified in the panel controller's settings in the Node Info window. == Panel Editor Tools == There are eight tool buttons at the top of the Panel Editor window, and they have the following uses. In addition to clicking on the tool button, some of these tools can also be selected by pressing the number key shown in the table. {| {{Table}} {{Tablehead3|Icon|Shortcut|Function}} |- {{Tablerow3|[[File:Tool_select.png]]|1|'''Select Widgets'''. This tool can be used to safely select items without the possibility of accidentally moving them. To select a single widget inside a group instead of the group itself, hold in the Control key while clicking.}} |- {{Tablerow3|[[File:Tool_move.png]]|2|'''Move Widgets'''. Selects and moves widgets. Holding down the Shift key while moving constrains the movement to a single axis.}} |- {{Tablerow3|[[File:Tool_rotate.png]]|3|'''Rotate Widgets'''. Selects and rotates widgets. Click and drag a handle for a selected widget to rotate. Holding down the Shift key while rotating snaps the angle to 45 degree increments.}} |- {{Tablerow3|[[File:Tool_resize.png]]|4|'''Resize Widgets'''. Selects and resizes widgets. Click and drag a handle for a selected widget to resize. Holding down the Shift key while resizing constrains the proportional width and height.}} |- {{Tablerow3|[[File:Tool_texoffset.png]]||'''Offset Texture'''. Offsets the texture within the selected image widgets.}} |- {{Tablerow3|[[File:Tool_texscale.png]]||'''Scale Texture'''. Scales the texture within the selected image widgets.}} |- {{Tablerow3|[[File:Tool_scroll.png]]|6|'''Scroll'''. Scrolls the panel viewport. Holding down the Alt key temporarily selects the scroll tool.}} |- {{Tablerow3|[[File:Tool_zoom.png]]|7|'''Zoom'''. Zooms the panel viewport. Dragging vertically with this tool zooms in and out of a viewport. Using the mouse wheel with any other tool also zooms.}} |} == Pages == The following table describes the individual pages that are currently available in the Panel Editor. {| {{Table}} {{Tablehead|Page|Description}} |- {{Tablerow|[[File:Panel_widgets.png]]|'''Widgets'''. To place a new widget in the panel, select a type of widget from the list in this page and drag out a rectangle in the viewport.}} |- {{Tablerow|[[File:Panel_transform.png]]|'''Transform'''. This page allows you to enter the position, rotation angle, and size of a selected widget. The position and size are measured in pixels, and the rotation angle is measured in degrees.}} |- {{Tablerow|[[File:Panel_grid.png]]|'''Grid'''. The toggle buttons in this page control grid visibility and whether grid snapping is enabled.}} |} == Widget Settings == When one or more widgets are selected, their properties can be edited on the right side of the window. Different properties are shown depending on the types of the selected widgets, but all widgets have an identifier, a color, two flags indicating whether the widget is initially disabled or hidden, and settings for a help balloon. Settings that differ among multiple selected widgets are displayed in an indeterminate state until they are modified. See the [[Widgets | list of widgets]] for a description of the settings that are specific to each type of widget. === Common Settings === * The '''Widget identifier''' is a string of up to 15 characters used to identify widgets from C++ code or a script. It can be left blank for widgets that will not be referenced. This identifier does not need to be unique. When a script uses an identifier to operate on widgets in a panel, it affects all widgets within the panel having that same widget identifier. * The'''Widget color''' is the primary color used by a widget. The exact way in which this color is used depends on the type of the widget. * The '''Initially disabled''' check box indicates whether the widget is initially disabled so that it can't be clicked. * The '''Initially hidden''' check box indicates whether the item is initially hidden so that it isn't rendered. * The '''Balloon type''' menu specifies what kind of help balloon is assigned to the widget. * The '''Balloon string''' is a string that is interpreted based on the type of balloon. If the balloon type is a text string, then the balloon string is displayed directly in the help balloon for the widget. If the balloon type is a panel resource, then the balloon string is the name of the panel resource that gets loaded and displayed in the balloon. == Menu Commands == === Panel Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Close'''|Ctrl-W|Closes the panel editor window.}} |- {{Tablerow3|'''Save Panel'''|Ctrl-S|Saves the current panel.}} |- {{Tablerow3|'''Save Panel As...'''|Ctrl-Shift-S|Saves the current panel after prompting for a file name. (Available only for panel resources, not in-game panel effects.)}} |- {{Tablerow3|'''Window Settings...'''|Ctrl-P|Opens a dialog in which the window dimensions, its title, and various options can be set. (Panel resources only.)}} |} === Edit Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Undo'''|Ctrl-Z|Undoes the last action. (Supports multiple undo.)}} |- {{Tablerow3|'''Cut'''|Ctrl-X|Cuts the current selection to the clipboard.}} |- {{Tablerow3|'''Copy'''|Ctrl-C|Copies the current selection to the clipboard.}} |- {{Tablerow3|'''Paste'''|Ctrl-V|Pastes the contents of the clipboard to the panel.}} |- {{Tablerow3|'''Clear'''|Delete|Deletes the current selection.}} |- {{Tablerow3|'''Select All'''|Ctrl-A|Selects every widget in the panel.}} |- {{Tablerow3|'''Duplicate'''|Ctrl-D|Duplicates the selected widgets.}} |} === Widget Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Bring to Front'''|Ctrl-Shift-&#93;|Brings the selected widgets to the front so that they are rendered last.}} |- {{Tablerow3|'''Bring Forward'''|Ctrl-&#93;|Brings each selected widget forward ahead of the next widget that would be rendered.}} |- {{Tablerow3|'''Send Backward'''|Ctrl-&#91;|Sends each selected widget backward behind the previous widget that would be rendered.}} |- {{Tablerow3|'''Send to Bac'''k|Ctrl-Shift-&#91;|Sends the selected widgets to the back so that they are rendered first.}} |- {{Tablerow3|'''Hide Selection'''|Ctrl-H|Hides the selected widgets.}} |- {{Tablerow3|'''Unhide All'''|Ctrl-Shift-H|Shows all widgets in the panel.}} |- {{Tablerow3|'''Lock Selection'''|Ctrl-L|Locks the selected widgets so that they can no longer be selected.}} |- {{Tablerow3|'''Unlock All'''|Ctrl-Shift-L|Unlocks all widgets in the panel.}} |- {{Tablerow3|'''Group Selection'''|Ctrl-G|Groups the selected widgets. (No groups can be selected.)}} |- {{Tablerow3|'''Ungroup Selection'''|Ctrl-Shift-G|Ungroups the selected groups.}} |- {{Tablerow3|'''Reset Rotation'''|Ctrl-R|Removes any rotation from the selected widgets.}} |- {{Tablerow3|'''Reset Texcoords'''|Ctrl-T|Resets the texture coordinates for selected image widgets to the default values.}} |- {{Tablerow3|'''Auto-scale Texture'''|Ctrl-F|Scales, or &ldquo;fixes&rdquo;, the texture coordinates of selected image widgets so that the aspect ratio is 1:1.}} |- {{Tablerow3|'''Edit Script'''|Ctrl-E|Opens the script editor for the selected widget. (Available only for in-game panel effects.)}} |- {{Tablerow3|'''Delete Script'''||Removes any scripts from the selected widgets.}} |} === Arrange Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Nudge Left'''|Ctrl-Left|Nudges the selected widgets one pixel to the left.}} |- {{Tablerow3|'''Nudge Right'''|Ctrl-Right|Nudges the selected widgets one pixel to the right.}} |- {{Tablerow3|'''Nudge Up'''|Ctrl-Up|Nudges the selected widgets one pixel upward.}} |- {{Tablerow3|'''Nudge Down'''|Ctrl-Down|Nudges the selected widgets one pixel downward.}} |- {{Tablerow3|'''Align Left Sides'''|Ctrl-Shift-Left|Aligns the left sides of the selected widgets to the leftmost point in the selection.}} |- {{Tablerow3|'''Align Right Sides'''|Ctrl-Shift-Right|Aligns the right sides of the selected widgets to the rightmost point in the selection.}} |- {{Tablerow3|'''Align Top Sides'''|Ctrl-Shift-Up|Aligns the top sides of the selected widgets to the topmost point in the selection.}} |- {{Tablerow3|'''Align Bottom Sides'''|Ctrl-Shift-Down|Aligns the bottom sides of the selected widgets to the bottommost point in the selection.}} |- {{Tablerow3|'''Align Horizontal Centers'''||Aligns the horizontal centers of the selected widgets to the average between the leftmost and rightmost points in the selection.}} |- {{Tablerow3|'''Align Vertical Centers'''||Aligns the vertical centers of the selected widgets to the average between the topmost and bottommost points in the selection.}} |} == See Also == * [[Widgets]] * [[Sprockets]] * [[Slug Effects]] [[Category:Interface]] 93182b59b7bb2e70110312155360891f8bdf78df 540 539 2023-11-08T21:18:07Z Eric Lengyel 1 /* Creating and Editing Panels */ wikitext text/x-wiki [[File:Paneleditor.png|right|frame|'''Figure 1.''' The Panel Editor window.]] The '''Panel Editor''', shown in the image to the right, is a tool included with the C4 Engine that is used to create and edit graphical user interfaces of two different types. First, the panel editor can be used to create windows, dialogs, and heads-up displays that are rendered on top of a game on a two-dimensional desktop, and these interfaces are saved in individual panel resource files. Second, the panel editor can be used to create interactive in-game interface panels that are saved as part of the world in which they exist. An interface panel is composed of a set of widgets, and many different types of widgets, including simple text and image widgets and more complex widgets like list boxes, are built into the engine. Custom widget subclasses can be defined in the game code and registered with the engine so they appear in the Panel Editor. Each widget can have one or more ''[[sprockets]]'' attached to it that produce animations of various kinds. Widgets belonging to in-game interface panels can also have scripts attached to them that get executed when the user interacts with the widgets. == Creating and Editing Panels == === Desktop Panel Resources === New panel resources can be created, and existing panel resources can be edited, by choosing the New Panel or Open Panel commands in the [[C4 Menu]]. The <code>panel</code> command can also be entered in the [[Command Console]] to open an existing panel resource. The dimensions, window title, and various flags for a desktop user interface panel are set by choosing Window Settings from the Panel menu. After saving the panel, the created <code>.pan</code> file can then be used in your game with the [http://c4engine.com/docs/InterfaceMgr/Window.html Window] class. === In-Game Panel Effects === An interface panel can be created in the World Editor by using the Panel Effect tool in the [[Effects Page]]. When a panel effect is selected, the Panel Editor can be opened for it by choosing &ldquo;Edit Script or Panel&rdquo; from the Node menu, which has the shortcut Ctrl-E. The Panel Editor is also accessible from the Controller pane in the Node Info window. The Panel Effect tool draws a rectangular region representing the boundary of the panel. When a panel is first created, it automatically has a Panel Controller assigned to it that can be accessed under the Controller pane in the Node Info window. An in-game panel possesses both its physical size in the world, as drawn with the Panel Effect tool, and an internal interface resolution. The resolution is adjusted in the properties for the Panel Controller. The interface resolution determines how big the virtual screen is on which items will be placed with the Panel Editor. Whatever resolution is chosen, the entire panel is fit precisely into the physical dimensions determined by the rectangle drawn in the World Editor. Thus, it's usually desirable to match the aspect ratios of both the panel's physical size and its interface resolution to avoid stretching the contents of the panel. Under the '''Panel''' tab in the Node Info window, there are three check boxes that affect how the panel is rendered. * The '''Apply depth offset''' flag causes the panel to be rendered with a small depth offset forward. This avoids z-fighting artifacts that could otherwise appear if a panel was drawn in the same plane as background geometry. * The '''Render two-sided''' flag causes the panel to be rendered regardless of on which side of the panel's plane the camera currently is. This lets the panel be seen from the back if it's drawn on a transparent surface or floating in mid-air. * The '''Render with fog''' flag allows fog to be rendered over a panel. This must be explicitly enabled in order for a panel to be rendered in a fogged environment. A panel effect can be made interactive by assigning the Interaction property to it under the Properties pane of the Node Info window. An interactive panel can display a cursor on top of the panel while the user is engaged with it. The cursor is drawn as a vector icon, which is specified in the panel controller's settings in the Node Info window. == Panel Editor Tools == There are eight tool buttons at the top of the Panel Editor window, and they have the following uses. In addition to clicking on the tool button, some of these tools can also be selected by pressing the number key shown in the table. {| {{Table}} {{Tablehead3|Icon|Shortcut|Function}} |- {{Tablerow3|[[File:Tool_select.png]]|1|'''Select Widgets'''. This tool can be used to safely select items without the possibility of accidentally moving them. To select a single widget inside a group instead of the group itself, hold in the Control key while clicking.}} |- {{Tablerow3|[[File:Tool_move.png]]|2|'''Move Widgets'''. Selects and moves widgets. Holding down the Shift key while moving constrains the movement to a single axis.}} |- {{Tablerow3|[[File:Tool_rotate.png]]|3|'''Rotate Widgets'''. Selects and rotates widgets. Click and drag a handle for a selected widget to rotate. Holding down the Shift key while rotating snaps the angle to 45 degree increments.}} |- {{Tablerow3|[[File:Tool_resize.png]]|4|'''Resize Widgets'''. Selects and resizes widgets. Click and drag a handle for a selected widget to resize. Holding down the Shift key while resizing constrains the proportional width and height.}} |- {{Tablerow3|[[File:Tool_texoffset.png]]||'''Offset Texture'''. Offsets the texture within the selected image widgets.}} |- {{Tablerow3|[[File:Tool_texscale.png]]||'''Scale Texture'''. Scales the texture within the selected image widgets.}} |- {{Tablerow3|[[File:Tool_scroll.png]]|6|'''Scroll'''. Scrolls the panel viewport. Holding down the Alt key temporarily selects the scroll tool.}} |- {{Tablerow3|[[File:Tool_zoom.png]]|7|'''Zoom'''. Zooms the panel viewport. Dragging vertically with this tool zooms in and out of a viewport. Using the mouse wheel with any other tool also zooms.}} |} == Pages == The following table describes the individual pages that are currently available in the Panel Editor. {| {{Table}} {{Tablehead|Page|Description}} |- {{Tablerow|[[File:Panel_widgets.png]]|'''Widgets'''. To place a new widget in the panel, select a type of widget from the list in this page and drag out a rectangle in the viewport.}} |- {{Tablerow|[[File:Panel_transform.png]]|'''Transform'''. This page allows you to enter the position, rotation angle, and size of a selected widget. The position and size are measured in pixels, and the rotation angle is measured in degrees.}} |- {{Tablerow|[[File:Panel_grid.png]]|'''Grid'''. The toggle buttons in this page control grid visibility and whether grid snapping is enabled.}} |} == Widget Settings == When one or more widgets are selected, their properties can be edited on the right side of the window. Different properties are shown depending on the types of the selected widgets, but all widgets have an identifier, a color, two flags indicating whether the widget is initially disabled or hidden, and settings for a help balloon. Settings that differ among multiple selected widgets are displayed in an indeterminate state until they are modified. See the [[Widgets | list of widgets]] for a description of the settings that are specific to each type of widget. === Common Settings === * The '''Widget identifier''' is a string of up to 15 characters used to identify widgets from C++ code or a script. It can be left blank for widgets that will not be referenced. This identifier does not need to be unique. When a script uses an identifier to operate on widgets in a panel, it affects all widgets within the panel having that same widget identifier. * The'''Widget color''' is the primary color used by a widget. The exact way in which this color is used depends on the type of the widget. * The '''Initially disabled''' check box indicates whether the widget is initially disabled so that it can't be clicked. * The '''Initially hidden''' check box indicates whether the item is initially hidden so that it isn't rendered. * The '''Balloon type''' menu specifies what kind of help balloon is assigned to the widget. * The '''Balloon string''' is a string that is interpreted based on the type of balloon. If the balloon type is a text string, then the balloon string is displayed directly in the help balloon for the widget. If the balloon type is a panel resource, then the balloon string is the name of the panel resource that gets loaded and displayed in the balloon. == Menu Commands == === Panel Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Close'''|Ctrl-W|Closes the panel editor window.}} |- {{Tablerow3|'''Save Panel'''|Ctrl-S|Saves the current panel.}} |- {{Tablerow3|'''Save Panel As...'''|Ctrl-Shift-S|Saves the current panel after prompting for a file name. (Available only for panel resources, not in-game panel effects.)}} |- {{Tablerow3|'''Window Settings...'''|Ctrl-P|Opens a dialog in which the window dimensions, its title, and various options can be set. (Panel resources only.)}} |} === Edit Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Undo'''|Ctrl-Z|Undoes the last action. (Supports multiple undo.)}} |- {{Tablerow3|'''Cut'''|Ctrl-X|Cuts the current selection to the clipboard.}} |- {{Tablerow3|'''Copy'''|Ctrl-C|Copies the current selection to the clipboard.}} |- {{Tablerow3|'''Paste'''|Ctrl-V|Pastes the contents of the clipboard to the panel.}} |- {{Tablerow3|'''Clear'''|Delete|Deletes the current selection.}} |- {{Tablerow3|'''Select All'''|Ctrl-A|Selects every widget in the panel.}} |- {{Tablerow3|'''Duplicate'''|Ctrl-D|Duplicates the selected widgets.}} |} === Widget Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Bring to Front'''|Ctrl-Shift-&#93;|Brings the selected widgets to the front so that they are rendered last.}} |- {{Tablerow3|'''Bring Forward'''|Ctrl-&#93;|Brings each selected widget forward ahead of the next widget that would be rendered.}} |- {{Tablerow3|'''Send Backward'''|Ctrl-&#91;|Sends each selected widget backward behind the previous widget that would be rendered.}} |- {{Tablerow3|'''Send to Bac'''k|Ctrl-Shift-&#91;|Sends the selected widgets to the back so that they are rendered first.}} |- {{Tablerow3|'''Hide Selection'''|Ctrl-H|Hides the selected widgets.}} |- {{Tablerow3|'''Unhide All'''|Ctrl-Shift-H|Shows all widgets in the panel.}} |- {{Tablerow3|'''Lock Selection'''|Ctrl-L|Locks the selected widgets so that they can no longer be selected.}} |- {{Tablerow3|'''Unlock All'''|Ctrl-Shift-L|Unlocks all widgets in the panel.}} |- {{Tablerow3|'''Group Selection'''|Ctrl-G|Groups the selected widgets. (No groups can be selected.)}} |- {{Tablerow3|'''Ungroup Selection'''|Ctrl-Shift-G|Ungroups the selected groups.}} |- {{Tablerow3|'''Reset Rotation'''|Ctrl-R|Removes any rotation from the selected widgets.}} |- {{Tablerow3|'''Reset Texcoords'''|Ctrl-T|Resets the texture coordinates for selected image widgets to the default values.}} |- {{Tablerow3|'''Auto-scale Texture'''|Ctrl-F|Scales, or &ldquo;fixes&rdquo;, the texture coordinates of selected image widgets so that the aspect ratio is 1:1.}} |- {{Tablerow3|'''Edit Script'''|Ctrl-E|Opens the script editor for the selected widget. (Available only for in-game panel effects.)}} |- {{Tablerow3|'''Delete Script'''||Removes any scripts from the selected widgets.}} |} === Arrange Menu === {| {{Table}} {{Tablehead3|Command|Shortcut|Description}} |- {{Tablerow3|'''Nudge Left'''|Ctrl-Left|Nudges the selected widgets one pixel to the left.}} |- {{Tablerow3|'''Nudge Right'''|Ctrl-Right|Nudges the selected widgets one pixel to the right.}} |- {{Tablerow3|'''Nudge Up'''|Ctrl-Up|Nudges the selected widgets one pixel upward.}} |- {{Tablerow3|'''Nudge Down'''|Ctrl-Down|Nudges the selected widgets one pixel downward.}} |- {{Tablerow3|'''Align Left Sides'''|Ctrl-Shift-Left|Aligns the left sides of the selected widgets to the leftmost point in the selection.}} |- {{Tablerow3|'''Align Right Sides'''|Ctrl-Shift-Right|Aligns the right sides of the selected widgets to the rightmost point in the selection.}} |- {{Tablerow3|'''Align Top Sides'''|Ctrl-Shift-Up|Aligns the top sides of the selected widgets to the topmost point in the selection.}} |- {{Tablerow3|'''Align Bottom Sides'''|Ctrl-Shift-Down|Aligns the bottom sides of the selected widgets to the bottommost point in the selection.}} |- {{Tablerow3|'''Align Horizontal Centers'''||Aligns the horizontal centers of the selected widgets to the average between the leftmost and rightmost points in the selection.}} |- {{Tablerow3|'''Align Vertical Centers'''||Aligns the vertical centers of the selected widgets to the average between the topmost and bottommost points in the selection.}} |} == See Also == * [[Widgets]] * [[Sprockets]] * [[Slug Effects]] [[Category:Interface]] cdd3d76796cdcb446040c571884930424a231392 Release Notes for Version 7.1 0 96 542 98 2024-05-17T22:57:42Z Eric Lengyel 1 wikitext text/x-wiki __NOTOC__ '''Release date:''' April 24, 2023 == Core Engine == * Luminance and chromaticity have been separated for most things that emit light. This applies to light sources, emission attributes, and several special effects. This essentially allows color to be chosen independently of brightness, which can be much higher than 1.0. Brightness is now measured in physical quantities appropriate for the type of object. Infinite lights have illuminance measured in kilolux (klx), point lights have luminous intensity measured in kilocandelas (kcd), and emissive objects have luminance measured in kilocandelas per square meter (kcd/m²). * The <code>ColorRGBA</code> class is now a subclass of the <code>ColorRGB</code> class. === Graphics Manager === * The reflection and refraction buffer formats have been changed to 16-bit floating-point. === Interface Manager === * The default GUI has been updated to a dark theme, and default font sizes have been made a little larger. === Math Library === * Functions for transforming objects with quaternions, motors (dual quaternions), and flectors have faster implementations in this release. == In Progress == There are several new features that are in progress as of this release: * The engine is transitioning from OpenGL to Vulkan. Some code is present in version 7.1, but it is not complete. * A new physically-based metallic material attribute is in progress. * A new fur shader is in progress. * The way that terrain is textured is being updated. 52a49b6d5a1e82684043f9c50639582d13ac691e Release Notes 0 8 545 10 2024-09-03T23:04:24Z Eric Lengyel 1 wikitext text/x-wiki __NOTOC__ == Version 7.x == {| {{Table}} {{Tablehead3|Version|Release Date|Release Notes}} |- {{Tablerow3|Version 7.2|3 September 2024|[[Release Notes for Version 7.2]]}} |- {{Tablerow3|Version 7.1|24 April 2023|[[Release Notes for Version 7.1]]}} |- {{Tablerow3|Version 7.0|22 March 2023|[[Release Notes for Version 7.0]]}} |} == Version 6.x == {| {{Table}} {{Tablehead3|Version|Release Date|Release Notes}} |- {{Tablerow3|Version 6.9|2 Nov 2018|[[Release Notes for Version 6.9]]}} |- {{Tablerow3|Version 6.5|30 Sep 2017|[[Release Notes for Version 6.5]]}} |- {{Tablerow3|Version 6.2|11 May 2017|[[Release Notes for Version 6.2]]}} |- {{Tablerow3|Version 6.1|29 Apr 2017|[[Release Notes for Version 6.1]]}} |- {{Tablerow3|Version 6.0|27 Jan 2017|[[Release Notes for Version 6.0]]}} |} == Version 5.x == {| {{Table}} {{Tablehead3|Version|Release Date|Release Notes}} |- {{Tablerow3|Version 5.5.1|6 Dec 2016|[[Release Notes for Version 5.5.1]]}} |- {{Tablerow3|Version 5.5|16 Nov 2016|[[Release Notes for Version 5.5]]}} |- {{Tablerow3|Version 5.0|20 Sep 2016|[[Release Notes for Version 5.0]]}} |} == Version 4.x == {| {{Table}} {{Tablehead3|Version|Release Date|Release Notes}} |- {{Tablerow3|Version 4.5|28 Mar 2015|[[Release Notes for Version 4.5]]}} |- {{Tablerow3|Version 4.2|11 Jan 2015|[[Release Notes for Version 4.2]]}} |- {{Tablerow3|Version 4.1|25 Dec 2014|[[Release Notes for Version 4.1]]}} |- {{Tablerow3|Version 4.0|14 Oct 2014|[[Release Notes for Version 4.0]]}} |} == Version 3.x == {| {{Table}} {{Tablehead3|Version|Release&nbsp;Date|Release Notes}} |- {{Tablerow3|Version 3.5.1|22 Jan 2014|[[Release Notes for Version 3.5.1]]}} |- {{Tablerow3|Version 3.5|8 Jan 2014|[[Release Notes for Version 3.5]]}} |- {{Tablerow3|Version 3.0|29 Jul 2013|[[Release Notes for Version 3.0]]}} |} == Version 2.x == {| {{Table}} {{Tablehead3|Version|Release&nbsp;Date|Release Notes}} |- {{Tablerow3|Version 2.10.3|31 Mar 2013|[[Release Notes for Version 2.10.3]]}} |- {{Tablerow3|Version 2.10.2|7 Mar 2013|[[Release Notes for Version 2.10.2]]}} |- {{Tablerow3|Version 2.10.1|1 Dec 2012|[[Release Notes for Version 2.10.1]]}} |- {{Tablerow3|Version 2.10|16 Nov 2012|[[Release Notes for Version 2.10]]}} |- {{Tablerow3|Version 2.9.1|1 Jun 2012|[[Release Notes for Version 2.9.1]]}} |- {{Tablerow3|Version 2.9|20 May 2012|[[Release Notes for Version 2.9]]}} |- {{Tablerow3|Version 2.8|17 Apr 2012|[[Release Notes for Version 2.8]]}} |- {{Tablerow3|Version 2.7.1|14 Nov 2011|[[Release Notes for Version 2.7.1]]}} |- {{Tablerow3|Version 2.7|30 Sep 2011|[[Release Notes for Version 2.7]]}} |- {{Tablerow3|Version 2.6|14 Jul 2011|[[Release Notes for Version 2.6]]}} |- {{Tablerow3|Version 2.5.5|14 Apr 2011|[[Release Notes for Version 2.5.5]]}} |- {{Tablerow3|Version 2.5.2|1 Mar 2011|[[Release Notes for Version 2.5.2]]}} |- {{Tablerow3|Version 2.5.1|14 Feb 2011|[[Release Notes for Version 2.5.1]]}} |- {{Tablerow3|Version 2.5|12 Feb 2011|[[Release Notes for Version 2.5]]}} |- {{Tablerow3|Version 2.1.2|27 Sep 2010|[[Release Notes for Version 2.1.2]]}} |- {{Tablerow3|Version 2.1.1|20 Sep 2010|[[Release Notes for Version 2.1.1]]}} |- {{Tablerow3|Version 2.1|8 Jul 2010|[[Release Notes for Version 2.1]]}} |- {{Tablerow3|Version 2.0|31 May 2010|[[Release Notes for Version 2.0]]}} |} == Version 1.x == {| {{Table}} {{Tablehead3|Version|Release&nbsp;Date|Release Notes}} |- {{Tablerow3|Version 1.5.9|28 Apr 2009|[[Release Notes for Version 1.5.9]]}} |- {{Tablerow3|Version 1.5.8|4 Apr 2009|[[Release Notes for Version 1.5.8]]}} |- {{Tablerow3|Version 1.5.5|21 Mar 2009|[[Release Notes for Version 1.5.5]]}} |- {{Tablerow3|Version 1.5.2|13 Feb 2009|[[Release Notes for Version 1.5.2]]}} |- {{Tablerow3|Version 1.5.1|8 Feb 2009|[[Release Notes for Version 1.5.1]]}} |- {{Tablerow3|Version 1.5|27 Dec 2008|[[Release Notes for Version 1.5]]}} |- {{Tablerow3|Version 1.4.10|25 Jul 2008|[[Release Notes for Version 1.4.10]]}} |- {{Tablerow3|Build 149|8 Jul 2008|[[Release Notes for Build 149]]}} |- {{Tablerow3|Build 148|13 Mar 2008|[[Release Notes for Build 148]]}} |- {{Tablerow3|Build 147|25 Feb 2008|[[Release Notes for Build 147]]}} |- {{Tablerow3|Build 146|7 Feb 2008|[[Release Notes for Build 146]]}} |- {{Tablerow3|Build 145|27 Nov 2007|[[Release Notes for Build 145]]}} |- {{Tablerow3|Build 144|9 Nov 2007|[[Release Notes for Build 144]]}} |- {{Tablerow3|Build 143|19 Oct 2007|[[Release Notes for Build 143]]}} |- {{Tablerow3|Build 142|9 Oct 2007|[[Release Notes for Build 142]]}} |- {{Tablerow3|Build 141|3 Oct 2007|[[Release Notes for Build 141]]}} |- {{Tablerow3|Build 140|27 Sep 2007|[[Release Notes for Build 140]]}} |- {{Tablerow3|Build 139|21 Aug 2007|[[Release Notes for Build 139]]}} |- {{Tablerow3|Build 138|18 Aug 2007|[[Release Notes for Build 138]]}} |- {{Tablerow3|Build 137|4 Aug 2007|[[Release Notes for Build 137]]}} |- {{Tablerow3|Build 136|22 May 2007|[[Release Notes for Build 136]]}} |- {{Tablerow3|Build 135|12 May 2007|[[Release Notes for Build 135]]}} |- {{Tablerow3|Build 134|14 Apr 2007|[[Release Notes for Build 134]]}} |- {{Tablerow3|Build 133|6 Apr 2007|[[Release Notes for Build 133]]}} |- {{Tablerow3|Build 132|14 Feb 2007|[[Release Notes for Build 132]]}} |- {{Tablerow3|Build 131|20 Nov 2006|[[Release Notes for Build 131]]}} |- {{Tablerow3|Build 130|10 Nov 2006|[[Release Notes for Build 130]]}} |- {{Tablerow3|Build 129|3 Nov 2006|[[Release Notes for Build 129]]}} |- {{Tablerow3|Build 128|1 Oct 2006|[[Release Notes for Build 128]]}} |- {{Tablerow3|Build 127|15 Sep 2006|[[Release Notes for Build 127]]}} |- {{Tablerow3|Build 126|31 Aug 2006|[[Release Notes for Build 126]]}} |- {{Tablerow3|Build 125|30 Jun 2006|[[Release Notes for Build 125]]}} |- {{Tablerow3|Build 124|25 Jun 2006|[[Release Notes for Build 124]]}} |- {{Tablerow3|Build 123|6 Jun 2006|[[Release Notes for Build 123]]}} |- {{Tablerow3|Build 122|24 May 2006|[[Release Notes for Build 122]]}} |- {{Tablerow3|Build 121|24 Apr 2006|[[Release Notes for Build 121]]}} |- {{Tablerow3|Build 120|20 Apr 2006|[[Release Notes for Build 120]]}} |- {{Tablerow3|Build 119|18 Apr 2006|[[Release Notes for Build 119]]}} |- {{Tablerow3|Build 118|28 Mar 2006|[[Release Notes for Build 118]]}} |- {{Tablerow3|Build 117|20 Mar 2006|[[Release Notes for Build 117]]}} |- {{Tablerow3|Build 116|28 Feb 2006|[[Release Notes for Build 116]]}} |- {{Tablerow3|Build 115|12 Jan 2006|[[Release Notes for Build 115]]}} |- {{Tablerow3|Build 114|9 Jan 2006|[[Release Notes for Build 114]]}} |- {{Tablerow3|Build 113|26 Dec 2005|[[Release Notes for Build 113]]}} |- {{Tablerow3|Build 112|19 Oct 2005|[[Release Notes for Build 112]]}} |- {{Tablerow3|Build 111|26 Jul 2005|[[Release Notes for Build 111]]}} |- {{Tablerow3|Build 110|5 Jul 2005|[[Release Notes for Build 110]]}} |- {{Tablerow3|Build 109|23 Jun 2005|[[Release Notes for Build 109]]}} |- {{Tablerow3|Build 108|27 May 2005|[[Release Notes for Build 108]]}} |} == Ancient History == * [[Early C4 Engine Development Worklog]] ded23a91876a9f22d04ca5fb6234b92e7f5b0b4c Release Notes for Version 1.5.9 0 61 550 63 2024-12-06T06:46:22Z Eric Lengyel 1 wikitext text/x-wiki __NOTOC__ '''Release date:''' April 28, 2009 == Core Engine == === Shaders === * The Expand process has been added to the engine. It multiplies the input by 2.0 and then subtracts 1.0. This is useful for expanding values from the [0,1] range to the [&minus;1,1] range. (Note that the Normal Map process already implicitly expands the values read from its texture, so it's not necessary to use an Expand process after a normal map is read.) === Scripts === * A new Set External Variable method has been added to the Basic tab in the Script Editor. This method can set the value of an object-scope variable in another script to the value of any local variable belonging to the script that is running. === Miscellaneous === * Bone nodes in a model are now identified by a hash value derived from the bone's name instead of an index number based on the bone's position within the model. What this means is that any skinned mesh can be copied from one skeleton and pasted onto another skeleton as long as the bones that it needs exist in the new skeleton. There is no longer any requirement that the two skeletons have the same number of bones or that they occur in the same order within the skeletal hierarchy. * Normal maps can now be compressed using ordinary S3TC when the alpha channel is unused (which disqualifies parallax maps). Compressed normal maps only contain information in the green and alpha channels of the texture after they've been imported. These provide an 8-bit ''x'' component and a 6-bit ''y'' component for each normal vector, and the ''z'' component is reconstituted in a slightly more expensive fragment program. * A new <code>ShockwaveEffect</code> class has been added to the engine, and it produces an expanding distortion ring in the scene. This effect is implemented in the Extras plugin module, and the <code>ShellEffect</code> class has also been moved to the Extras plugin. * The <code>kControllerLocal</code> flag can now be specified by a controller to indicate that it operates autonomously and does not need to receive messages from remote machines. This flag would ordinarily be set in the controller's <code>Preprocess()</code> function before calling the base class's <code>Preprocess()</code> function, and it prevents the controller from being added to the world's controller array or being assigned a controller index. * With this release, official support for PowerPC-based Macs has been discontinued. However, the engine still builds and runs just fine on PowerPC processors. 7b49dc7b5b8639dd1eeaba8985ca26c2eac19636 Basic Shader Processes 0 427 551 430 2025-01-05T23:29:35Z Eric Lengyel 1 wikitext text/x-wiki This is a list of the basic shader processes that are available in the [[Shader Editor]] under the Basic tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Constant Scalar|Shader_constantscalar.png|None|Scalar|Outputs a constant scalar value that is specified in the settings for the process. A ''parameter slot'' may be specified in the process settings. If the parameter slot is set to &ldquo;Constant&rdquo; (the default), then the output of this process can never be changed while rendering. However, if one of the eight numbered parameter slots is selected, then it is possible to change the value output by this process without actually modifying the shader. For instance, the Set Shader Parameter script method can be used to change the output value of this process, effectively making it a variable parameter of the shader.}} |- {{Process|Constant Vector|Shader_constantvector.png|None|4D vector|Outputs a constant vector value that is specified in the settings for the process. See the note about parameter slots under the Constant Scalar process.}} |- {{Process|Constant Color|Shader_constantcolor.png|None|RGBA color|Outputs a constant color value that is specified in the settings for the process. This color has components in the range 0 to 1, and it typically represents reflective colors. See the note about parameter slots under the Constant Scalar process.}} |- {{Process|Constant Luminance|Shader_constantluminance.png|None|RGBA color|Outputs a constant luminance value that is specified in the settings for the process. This luminance has unlimited range, and it typically represents lighting or emissive colors. See the note about parameter slots under the Constant Scalar process.}} |- {{Process|Shader Time|Shader_time.png|None|Scalar|Outputs a scalar value in the range [0,1) representing the current shader time. The shader time runs from 0 to 1 over a period of 120 seconds and then repeats by wrapping back to 0.}} |- {{Process|Fragment Depth|Shader_fragmentdepth.png|None|Scalar|Outputs a scalar value equal to the depth of the fragment in camera space.}} |- {{Process|Primitive Facing|Shader_primitivefacing.png|None|Scalar|Outputs a scalar value that is +1.0 for front-facing primitives and &minus;1.0 for back-facing primitives.}} |- {{Process|Merge 2D|Shader_merge2d.png|Scalar '''x''' (required), Scalar '''y''' (required)|2D vector|Combines the two scalar inputs '''x''' and '''y''' into a single 2D vector output.}} |- {{Process|Merge 3D|Shader_merge3d.png|Scalar '''x''' (required), Scalar '''y''' (required), Scalar '''z''' (required)|3D vector|Combines the three scalar inputs '''x''', '''y''', and '''z''' into a single 3D vector output.}} |- {{Process|Merge 4D|Shader_merge4d.png|Scalar '''x''' (required), Scalar '''y''' (required), Scalar '''z''' (required), Scalar '''w''' (required)|4D vector|Combines the four scalar inputs '''x''', '''y''', '''z''', and '''w''' into a single 4D vector output.}} |- {{Process|Texture Map|Shader_texturemap.png|2D or 3D vector '''TEXC''' (required)|RGBA color|Samples a texture map using the input texture coordinates '''TEXC'''. The texture map is specified in the settings for the process. The size of the input '''TEXC''' is determined by the type of the texture map. The input is a 2D vector for 2D and Rect textures, and the size is a 3D vector for 3D, Cube, and Array 2D textures. Note that this process should not be used for normal maps. Use the Normal Map process instead.}} |- {{Process|Normal Map|Shader_normalmap.png|2D vector '''TEXC''' (required)|3D vector|Samples a normal map using the input texture coordinates '''TEXC'''. The normal map is specified in the settings for the process.}} |- {{Process|Paint Texture|Shader_painttexture.png|2D vector '''TEXC''' (required)|RGBA color|Samples a paint space texture map using the input texture coordinates '''TEXC'''. The texture map is determined by what paint space is associated with the geometry being rendered. The input vector is normally the output of the Paint Texcoord [[Interpolant Shader Processes|interpolant process]].}} |- {{Process|Terrain Texture|Shader_terraintexture.png|None|RGBA color|Samples a terrain texture palette. The texture map is specified in the settings for the process. Note that this process should not be used for terrain normal maps. Use the Terrain Normal process instead.}} |- {{Process|Terrain Normal 1, 2, 3|Shader_terrainnormal1.png|None|3D vector|Samples a terrain normal palette. The normal map is specified in the settings for the process. If one of these three processes exists, then all three should exist and should use the same normal map. Their outputs should be sent to a Terrain Diffuse Reflection and/or Terrain Specular Reflection process.}} |- {{Process|Impostor Texture|Shader_impostortexture.png|None|RGBA color|Samples an impostor texture map. The texture map is specified in the settings for the process. Note that this process should not be used for impostor normal maps. Use the Impostor Normal process instead.}} |- {{Process|Impostor Normal|Shader_impostornormal.png|None|3D vector|Samples an impostor normal map. The normal map is specified in the settings for the process.}} |} == See Also == * [[Shader Editor]] * [[Mathematical Shader Processes]] * [[Complex Shader Processes]] * [[Interpolant Shader Processes]] [[Category:Shaders]] 248b41ed5b290352a6a3c4d95ba6b2e6cc8188e3 File:Shader texcoord1.png 6 332 552 334 2025-01-06T02:05:00Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader texcoord1.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Template:Process 10 425 553 428 2025-01-06T02:06:17Z Eric Lengyel 1 wikitext text/x-wiki | style="text-align: center; vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 24px 2px 6px;" | '''{{{1}}}''' [[File:{{{2}}}|256px]] | style="vertical-align: top; background-color: #F6F6F6; border: solid 1px #444; padding: 2px 6px 2px 6px;" | '''Inputs:''' {{{3}}} '''Output:''' {{{4}}} {{{5}}} 375c80eabe1f2bf55d7cfc3ee5a9aa33d96cb94f File:Shader painttexcoord.png 6 299 554 301 2025-01-06T02:08:02Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader painttexcoord.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 556 554 2025-01-06T02:09:31Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader painttexcoord.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader texcoord2.png 6 333 555 335 2025-01-06T02:08:55Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader texcoord2.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader vertexcolor.png 6 336 557 338 2025-01-06T02:10:13Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader vertexcolor.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader vertexgeometry.png 6 337 558 339 2025-01-06T02:10:28Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader vertexgeometry.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader tangentlight.png 6 324 559 326 2025-01-06T02:11:13Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader tangentlight.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader tangentview.png 6 326 560 328 2025-01-06T02:11:35Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader tangentview.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader tangenthalfway.png 6 323 561 325 2025-01-06T02:11:50Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader tangenthalfway.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader objectlight.png 6 294 562 296 2025-01-06T02:12:10Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader objectlight.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader objectview.png 6 298 563 300 2025-01-06T02:12:45Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader objectview.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader objecthalfway.png 6 293 564 295 2025-01-06T02:13:10Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader objecthalfway.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader objectposition.png 6 296 565 298 2025-01-06T02:13:38Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader objectposition.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader objectnormal.png 6 295 566 297 2025-01-06T02:13:58Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader objectnormal.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader objecttangent.png 6 297 567 299 2025-01-06T02:14:16Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader objecttangent.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader objectbitangent.png 6 292 568 294 2025-01-06T02:14:30Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader objectbitangent.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader worldposition.png 6 340 569 342 2025-01-06T02:14:49Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader worldposition.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader worldnormal.png 6 339 570 341 2025-01-06T02:15:06Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader worldnormal.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader worldtangent.png 6 341 571 343 2025-01-06T02:15:21Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader worldtangent.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader worldbitangent.png 6 338 572 340 2025-01-06T02:15:36Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader worldbitangent.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Interpolant Shader Processes 0 430 573 433 2025-01-06T02:18:44Z Eric Lengyel 1 wikitext text/x-wiki __NOTOC__ When the graphics hardware renders a triangle, some values are calculated at each pixel and other values are calculated only at the vertices. The values calculated at the vertices are smoothly varied across the interior of a triangle through a process called perspective-correct interpolation. Hence, these values are called ''interpolants''. The list below describes each of the interpolants available for use in the [[Shader Editor]] under the Interpolants tab. == Interpolant Allocation == The graphics hardware can only handle so many interpolants, so there is a limit to how many can be used in a single shader. (The ambient and light graphs shown in the editor represent distinct shaders, so any interpolants used in one do not count against the other.) The limit is based on the availability of eight 4D vectors that the hardware provides for texture coordinates, or ''texcoords''. We call these the eight texcoord slots. Among these slots, there are a total of exactly 32 scalar values that can be calculated at each vertex and interpolated across a triangle. However, interpolants that need 2, 3, or 4 values cannot be split up, so it may not be possible to pack all of the interpolants into the texcoord slots even though there is enough room for each of the component values. Furthermore, lighting and fog calculations that are not explicitly displayed in the shader graph need some of their own interpolants, so the number of usable texcoord slots is somewhat less than the full eight that exist in the hardware. The shader compiler allocates interpolants to texcoord slots as follows: * For any four-component interpolant, one entire texcoord slot is consumed. * For any three-component interpolant, the first three components of a single texcoord slot are consumed. The fourth component can be used by a different one-component interpolant. * For any two-component interpolant, either the first two or last two components of a single texcoord slot are consumed. If the first half of a texcoord slot is allocated, then the second half can be used by another two-component interpolant, or it can be used by two one-component interpolants. * For any one-component interpolant, the first available unused component of any texcoord slot is consumed. Interpolants are allocated in order of size from largest to smallest so that a bunch of small interpolants can't prevent a large interpolant from being allocated when there should be room. Unless otherwise noted below, each interpolant provided in the Shader Editor requires the number of components in its output value. == Coordinate Spaces == There are three different coordinate systems that can be used in shaders: tangent-space coordinates, object-space coordinates, and world-space coordinates. ''Tangent space'' is a special coordinate system that is required for normal mapping. In tangent space, the ''z'' axis is always aligned with the vertex normal, and the ''x'' axis is always aligned with the vertex tangent (which is aligned with the ''s'' direction of the texture coordinates). In the interior of a triangle, the tangent space is a blend of the tangent spaces at each of the three vertices. By definition, the normal vector in tangent space is always (0,0,1). Similarly, the tangent direction is always (1,0,0), and the bitangent direction is always (0,1,0). ''Object space'' is the local coordinate space for an individual object. In object space, the normals and tangents are exactly those that are stored in the vertex arrays for an object. It is unusual for object-space coordinates to be used in a shader. The use of tangent-space coordinates is preferred because it is more efficient. ''World space'' is the global coordinate system. The use of world-space coordinates is normally only needed when sampling cube texture maps. == Interpolants == {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Texcoord 1|Shader_texcoord1.png|None|2D vector|The primary texture coordinates.}} |- {{Process|Texcoord 2|Shader_texcoord2.png|None|2D vector|The secondary texture coordinates.}} |- {{Process|Paint Texcoord|Shader_painttexcoord.png|None|2D vector|The paint space texture coordinates. These are determined by the paint space associated with the geometry being rendered. The output of this process is normally fed into a Paint Texture [[Basic Shader Processes|basic process]].}} |- {{Process|Vertex Color|Shader_vertexcolor.png|None|RGBA color|The vertex color. The vertex color does not occupy any texcoord slots.}} |- {{Process|Vertex Geometry|Shader_vertexgeometry.png|None|3D vector|This interpolant can be used with water shaders when land elevation data has been generated for water geometries. The ''z'' component contains the difference in height between the water surface and the land beneath it, and the ''x'' and ''y'' components contain the gradient of the land elevation.}} |- {{Process|Tangent-Space Light Direction|Shader_tangentlight.png|None|3D vector|The unit-length tangent-space direction to light '''L'''. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Tangent-Space View Direction|Shader_tangentview.png|None|3D vector|The unit-length tangent-space direction to viewer '''V'''.}} |- {{Process|Tangent-Space Halfway Direction|Shader_tangenthalfway.png|None|3D vector|The unit-length tangent-space direction vector '''H'''. The halfway direction does not occupy any texcoord slots by itself, but it implicitly requires the light direction and view direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Object-Space Light Direction|Shader_objectlight.png|None|3D vector|The unit-length object-space direction to light '''L'''. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Object-Space View Direction|Shader_objectview.png|None|3D vector|The unit-length object-space direction to viewer '''V'''.}} |- {{Process|Object-Space Halfway Direction|Shader_objecthalfway.png|None|3D vector|The unit-length object-space halfway direction '''H'''. The halfway direction does not occupy any texcoord slots by itself, but it implicitly requires the light direction and view direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Object-Space Vertex Position|Shader_objectposition.png|None|3D vector|The object-space vertex position '''P'''.}} |- {{Process|Object-Space Normal|Shader_objectnormal.png|None|3D vector|The object-space vertex normal '''N'''.}} |- {{Process|Object-Space Tangent|Shader_objecttangent.png|None|3D vector|The object-space vertex tangent '''T'''.}} |- {{Process|Object-Space Bitangent|Shader_objectbitangent.png|None|3D vector|The object-space vertex bitangent '''B'''.}} |- {{Process|World-Space Light Direction|Shader_worldlight.png|None|3D vector|The unit-length world-space direction to light '''L'''. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|World-Space View Direction|Shader_worldview.png|None|3D vector|The unit-length world-space direction to viewer '''V'''.}} |- {{Process|World-Space Halfway Direction|Shader_worldhalfway.png|None|3D vector|The unit-length world-space halfway direction '''H'''. The halfway direction does not occupy any texcoord slots by itself, but it implicitly requires the light direction and view direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|World-Space Vertex Position|Shader_worldposition.png|None|3D vector|The world-space vertex position '''P'''.}} |- {{Process|World-Space Normal|Shader_worldnormal.png|None|3D vector|The world-space vertex normal '''N'''.}} |- {{Process|World-Space Tangent|Shader_worldtangent.png|None|3D vector|The world-space vertex tangent '''T'''.}} |- {{Process|World-Space Bitangent|Shader_worldbitangent.png|None|3D vector|The world-space vertex bitangent '''B'''.}} |} == See Also == * [[Shader Editor]] * [[Basic Shader Processes]] * [[Mathematical Shader Processes]] * [[Complex Shader Processes]] [[Category:Shaders]] 4d36af21c3c3790f09ca272b58aaf79b4c7fad1b File:Shader worldlight.png 6 525 574 2025-01-06T02:19:04Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader worldview.png 6 526 575 2025-01-06T02:19:17Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader worldhalfway.png 6 527 576 2025-01-06T02:19:28Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Complex Shader Processes 0 429 577 432 2025-01-06T02:24:31Z Eric Lengyel 1 wikitext text/x-wiki This is a list of the complex shader processes that are available in the [[Shader Editor]] under the Complex tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Diffuse Reflection|Shader_diffuse.png|Tangent-space normal '''N''' (optional)|Scalar|Calculates the Lambertian diffuse reflection factor '''N'''&nbsp;&middot;&nbsp;'''L''', where '''L''' is the tangent-space direction to light. The result is saturated to the range [0,1]. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Specular Reflection|Shader_specular.png|Tangent-space normal '''N''' (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor ('''N'''&nbsp;&middot;&nbsp;'''H''')<sup>''p''</sup>, where '''H''' is the tangent-space direction halfway between the direction to light and direction to viewer. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). The specular power ''p'' controls the sharpness of the specularity. This process implicitly uses the tangent halfway direction interpolant, which in turn uses the tangent light direction and tangent view direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Microfacet Reflection|Shader_microfacet.png|Tangent-space normal '''N''' (optional)|RGB color|Calculates the Cook-Torrance microfacet reflection color. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). This process implicitly uses the tangent light direction, tangent view direction, and tangent halfway direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Terrain Diffuse Reflection|Shader_terraindiffuse.png|Terrain normal '''N'''<sub>1</sub> (optional), Terrain normal '''N'''<sub>2</sub> (optional), Terrain normal '''N'''<sub>3</sub> (optional)|Scalar|Calculates the Lambertian diffuse reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Terrain Specular Reflection|Shader_terrainspecular.png|Terrain normal '''N'''<sub>1</sub> (optional), Terrain normal '''N'''<sub>2</sub> (optional), Terrain normal '''N'''<sub>3</sub> (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. The specular power ''p'' controls the sharpness of the specularity. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Combine Normal Maps|Shader_combinenormals.png|Normal vector '''N'''<sub>1</sub> (required), Normal vector '''N'''<sub>2</sub> (required), Scalar ''t'' (optional)|3D vector|If ''t'' is omitted, calculates a new normal vector corresponding to the normal that would be produced if the two height maps producing the input normals were added together. If ''t'' is not omitted, then it determines how the heights are weighted, with the height corresponding to '''N'''<sub>1</sub> being weighted most when ''t'' is zero and the height corresponding to '''N'''<sub>2</sub> being weighted most when ''t'' is one. A value for ''t'' of 0.5 produces an average height, which is not the same as the sum produces when ''t'' is omitted.}} |- {{Process|Reflect Vector|Shader_reflectvector.png|3D vector '''V''' (required), 3D vector '''N''' (optional)|3D vector|Calculates the reflection of the vector '''V''' across the vector '''N'''. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).}} |- {{Process|Smooth Parameter|Shader_smooth.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 3''t''<sup>2</sup>&nbsp;&minus;&nbsp;2''t''<sup>3</sup> componentwise. This has the effect of smoothing an interpolation parameter within the range [0,1] since the derivative at both endpoints is zero.}} |- {{Process|Steep Parameter|Shader_steep.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 2''t''&nbsp;&minus;&nbsp;''t''<sup>2</sup> componentwise. This has the effect of making an interpolation start quickly at a steep slope and finish smoothly.}} |- {{Process|Linear Ramp|Shader_linearramp.png|Value '''A''' (required)|Value of size matching '''A'''|Remaps the range [''c''&nbsp;&minus;&nbsp;&frac12;''w'',&nbsp;''c''&nbsp;+&nbsp;&frac12;''w''] to the range [0,1] componentwise, where ''c'' is a center value and ''w'' is the width of the input range. The values of ''c'' and ''w'' are specified in the settings for the process.}} |- {{Process|Delta Depth|Shader_deltadepth.png|None|Scalar|Outputs the difference between the depth of the geometry in the structure buffer and the depth of the fragment being shaded, scaled by a factor ''s'' and clamped to the range [0,1]. The scale factor ''s'' is specified in the settings for the process. If rendering to the structure buffer is disabled, then the output value is always 1.0.}} |- {{Process|Tangent to World Transform|Shader_tangenttoworld.png|3D vector '''V''' (required)|3D vector|Transforms the vector '''V''' from tangent space coordinates into world space coordinates. This process implicitly uses three 3D vector interpolants containing the matrix that transforms from tangent space to world space.}} |- {{Process|Parallax Offset|Shader_parallax.png|2D vector '''TEXC''' (required)|2D vector|Perturbs the input texture coordinates using the parallax information in the normal map and outputs the result. The normal map is specified in the settings for the process. If parallax mapping is disabled, then the input texture coordinates '''TEXC''' are simply passed through to the output. This process implicitly uses the tangent view direction interpolant.}} |- {{Process|Horizon Shadow|Shader_horizon.png|2D vector '''TEXC''' (required), RGB color '''RGB''' (required)|RGB color|Calculates the horizon map shadowing based on the two input horizon map sampled at the texture coordinates '''TEXC''' and multiplies the input color '''RGB''' by the amount of light reaching the surface. The horizon map is specified in the settings for the process. Flags for excluding horizon mapping for infinite or points lights can also be set. If horizon mapping is disabled or the shader is used in conjunction with a light type that has been excluded, then the input color '''RGB''' is simply passed through to the output. This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Kill Fragment|Shader_kill.png|Scalar '''A''' (required), Scalar '''B''' (optional)|None|Kills the current fragment if '''A''' &lt; '''B'''. If '''B''' is omitted, then the fragment is killed if '''A''' &lt; 0.}} |} == See Also == * [[Shader Editor]] * [[Basic Shader Processes]] * [[Mathematical Shader Processes]] * [[Interpolant Shader Processes]] [[Category:Shaders]] a486d821f941356b6e27b6e4901023aeb610a5fe 580 577 2025-01-06T02:25:32Z Eric Lengyel 1 wikitext text/x-wiki This is a list of the complex shader processes that are available in the [[Shader Editor]] under the Complex tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Diffuse Reflection|Shader_diffuse.png|Tangent-space normal '''N''' (optional)|Scalar|Calculates the Lambertian diffuse reflection factor '''N'''&nbsp;&middot;&nbsp;'''L''', where '''L''' is the tangent-space direction to light. The result is saturated to the range [0,1]. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Specular Reflection|Shader_specular.png|Tangent-space normal '''N''' (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor ('''N'''&nbsp;&middot;&nbsp;'''H''')<sup>''p''</sup>, where '''H''' is the tangent-space direction halfway between the direction to light and direction to viewer. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). The specular power ''p'' controls the sharpness of the specularity. This process implicitly uses the tangent halfway direction interpolant, which in turn uses the tangent light direction and tangent view direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Terrain Diffuse Reflection|Shader_terraindiffuse.png|Terrain normal '''N'''<sub>1</sub> (optional), Terrain normal '''N'''<sub>2</sub> (optional), Terrain normal '''N'''<sub>3</sub> (optional)|Scalar|Calculates the Lambertian diffuse reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Terrain Specular Reflection|Shader_terrainspecular.png|Terrain normal '''N'''<sub>1</sub> (optional), Terrain normal '''N'''<sub>2</sub> (optional), Terrain normal '''N'''<sub>3</sub> (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. The specular power ''p'' controls the sharpness of the specularity. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Combine Normal Maps|Shader_combinenormals.png|Normal vector '''N'''<sub>1</sub> (required), Normal vector '''N'''<sub>2</sub> (required), Scalar ''t'' (optional)|3D vector|If ''t'' is omitted, calculates a new normal vector corresponding to the normal that would be produced if the two height maps producing the input normals were added together. If ''t'' is not omitted, then it determines how the heights are weighted, with the height corresponding to '''N'''<sub>1</sub> being weighted most when ''t'' is zero and the height corresponding to '''N'''<sub>2</sub> being weighted most when ''t'' is one. A value for ''t'' of 0.5 produces an average height, which is not the same as the sum produces when ''t'' is omitted.}} |- {{Process|Reflect Vector|Shader_reflectvector.png|3D vector '''V''' (required), 3D vector '''N''' (optional)|3D vector|Calculates the reflection of the vector '''V''' across the vector '''N'''. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).}} |- {{Process|Smooth Parameter|Shader_smooth.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 3''t''<sup>2</sup>&nbsp;&minus;&nbsp;2''t''<sup>3</sup> componentwise. This has the effect of smoothing an interpolation parameter within the range [0,1] since the derivative at both endpoints is zero.}} |- {{Process|Steep Parameter|Shader_steep.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 2''t''&nbsp;&minus;&nbsp;''t''<sup>2</sup> componentwise. This has the effect of making an interpolation start quickly at a steep slope and finish smoothly.}} |- {{Process|Linear Ramp|Shader_linearramp.png|Value '''A''' (required)|Value of size matching '''A'''|Remaps the range [''c''&nbsp;&minus;&nbsp;&frac12;''w'',&nbsp;''c''&nbsp;+&nbsp;&frac12;''w''] to the range [0,1] componentwise, where ''c'' is a center value and ''w'' is the width of the input range. The values of ''c'' and ''w'' are specified in the settings for the process.}} |- {{Process|Delta Depth|Shader_deltadepth.png|None|Scalar|Outputs the difference between the depth of the geometry in the structure buffer and the depth of the fragment being shaded, scaled by a factor ''s'' and clamped to the range [0,1]. The scale factor ''s'' is specified in the settings for the process. If rendering to the structure buffer is disabled, then the output value is always 1.0.}} |- {{Process|Tangent to World Transform|Shader_tangenttoworld.png|3D vector '''V''' (required)|3D vector|Transforms the vector '''V''' from tangent space coordinates into world space coordinates. This process implicitly uses three 3D vector interpolants containing the matrix that transforms from tangent space to world space.}} |- {{Process|Parallax Offset|Shader_parallax.png|2D vector '''TEXC''' (required)|2D vector|Perturbs the input texture coordinates using the parallax information in the normal map and outputs the result. The normal map is specified in the settings for the process. If parallax mapping is disabled, then the input texture coordinates '''TEXC''' are simply passed through to the output. This process implicitly uses the tangent view direction interpolant.}} |- {{Process|Horizon Shadow|Shader_horizon.png|2D vector '''TEXC''' (required), RGB color '''RGB''' (required)|RGB color|Calculates the horizon map shadowing based on the two input horizon map sampled at the texture coordinates '''TEXC''' and multiplies the input color '''RGB''' by the amount of light reaching the surface. The horizon map is specified in the settings for the process. Flags for excluding horizon mapping for infinite or points lights can also be set. If horizon mapping is disabled or the shader is used in conjunction with a light type that has been excluded, then the input color '''RGB''' is simply passed through to the output. This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Kill Fragment|Shader_kill.png|Scalar '''A''' (required), Scalar '''B''' (optional)|None|Kills the current fragment if '''A''' &lt; '''B'''. If '''B''' is omitted, then the fragment is killed if '''A''' &lt; 0.}} |} == See Also == * [[Shader Editor]] * [[Basic Shader Processes]] * [[Mathematical Shader Processes]] * [[Interpolant Shader Processes]] [[Category:Shaders]] 2bb215e930079c77b099bd2b7e8430182c78b4aa File:Shader diffuse.png 6 253 578 255 2025-01-06T02:25:00Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader diffuse.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader specular.png 6 319 579 321 2025-01-06T02:25:15Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader specular.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader terraindiffuse.png 6 327 581 329 2025-01-06T02:25:56Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader terraindiffuse.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader terrainspecular.png 6 330 582 332 2025-01-06T02:26:16Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader terrainspecular.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader combinenormals.png 6 246 583 248 2025-01-06T02:26:36Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader combinenormals.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader reflectvector.png 6 306 584 308 2025-01-06T02:26:59Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader reflectvector.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader smooth.png 6 317 585 319 2025-01-06T02:27:10Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader smooth.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader steep.png 6 321 586 323 2025-01-06T02:27:25Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader steep.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader linearramp.png 6 279 587 281 2025-01-06T02:27:41Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader linearramp.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader deltadepth.png 6 252 588 254 2025-01-06T02:27:54Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader deltadepth.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader tangenttoworld.png 6 325 589 327 2025-01-06T02:28:10Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader tangenttoworld.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader parallax.png 6 301 590 303 2025-01-06T02:28:25Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader parallax.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader horizon.png 6 271 591 273 2025-01-06T02:28:39Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader horizon.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader kill.png 6 276 592 278 2025-01-06T02:28:52Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader kill.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader constantscalar.png 6 249 593 251 2025-01-06T02:31:42Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader constantscalar.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader constantvector.png 6 250 594 252 2025-01-06T02:31:59Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader constantvector.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader constantcolor.png 6 248 595 250 2025-01-06T02:32:16Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader constantcolor.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader constantluminance.png 6 528 596 2025-01-06T02:32:29Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader time.png 6 335 597 337 2025-01-06T02:32:41Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader time.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader fragmentdepth.png 6 262 598 264 2025-01-06T02:33:02Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader fragmentdepth.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader primitivefacing.png 6 303 599 305 2025-01-06T02:33:17Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader primitivefacing.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader merge2d.png 6 284 600 286 2025-01-06T02:33:31Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader merge2d.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader merge3d.png 6 285 601 287 2025-01-06T02:33:44Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader merge3d.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader merge4d.png 6 286 602 288 2025-01-06T02:33:57Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader merge4d.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader texturemap.png 6 334 603 336 2025-01-06T02:34:11Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader texturemap.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader normalmap.png 6 291 604 293 2025-01-06T02:34:24Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader normalmap.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader painttexture.png 6 300 605 302 2025-01-06T02:34:37Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader painttexture.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader terraintexture.png 6 331 606 333 2025-01-06T02:34:55Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader terraintexture.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader terrainnormal1.png 6 329 607 331 2025-01-06T02:35:09Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader terrainnormal1.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader impostortexture.png 6 274 608 276 2025-01-06T02:35:24Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader impostortexture.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader impostornormal.png 6 273 609 275 2025-01-06T02:35:36Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader impostornormal.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 610 609 2025-01-06T02:41:28Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader impostornormal.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader abs.png 6 239 611 241 2025-01-06T02:42:37Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader abs.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader add.png 6 240 612 242 2025-01-06T02:42:58Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader add.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader avg.png 6 244 613 246 2025-01-06T02:43:14Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader avg.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader cos.png 6 251 614 253 2025-01-06T02:43:27Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader cos.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader xpd.png 6 342 615 344 2025-01-06T02:43:41Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader xpd.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader div.png 6 254 616 256 2025-01-06T02:43:52Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader div.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader dp3.png 6 255 617 257 2025-01-06T02:44:05Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader dp3.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader dp4.png 6 256 618 258 2025-01-06T02:44:17Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader dp4.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader ex2.png 6 259 619 261 2025-01-06T02:44:30Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader ex2.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader expand.png 6 260 620 262 2025-01-06T02:44:42Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader expand.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader flr.png 6 261 621 263 2025-01-06T02:44:56Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader flr.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader frc.png 6 263 622 265 2025-01-06T02:45:08Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader frc.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader invert.png 6 275 623 277 2025-01-06T02:45:22Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader invert.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader lrp.png 6 280 624 282 2025-01-06T02:45:35Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader lrp.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader lg2.png 6 277 625 279 2025-01-06T02:46:00Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader lg2.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader magnitude3d.png 6 282 626 284 2025-01-06T02:46:21Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader magnitude3d.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader max.png 6 283 627 285 2025-01-06T02:46:33Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader max.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader min.png 6 288 628 290 2025-01-06T02:46:47Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader min.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader mul.png 6 289 629 291 2025-01-06T02:47:01Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader mul.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader mad.png 6 281 630 283 2025-01-06T02:47:14Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader mad.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader normalize3d.png 6 290 631 292 2025-01-06T02:47:27Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader normalize3d.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader pow.png 6 302 632 304 2025-01-06T02:47:39Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader pow.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader rcp.png 6 304 633 306 2025-01-06T02:47:50Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader rcp.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader rsq.png 6 309 634 311 2025-01-06T02:48:03Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader rsq.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader round.png 6 308 635 310 2025-01-06T02:48:16Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader round.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sat.png 6 310 636 312 2025-01-06T02:48:28Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader sat.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader seq.png 6 311 637 313 2025-01-06T02:48:42Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader seq.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sge.png 6 312 638 314 2025-01-06T02:48:55Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader sge.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sgt.png 6 313 639 315 2025-01-06T02:49:09Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader sgt.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sle.png 6 315 640 317 2025-01-06T02:49:24Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader sle.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader slt.png 6 316 641 318 2025-01-06T02:50:28Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader slt.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sne.png 6 318 642 320 2025-01-06T02:50:44Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader sne.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sin.png 6 314 643 316 2025-01-06T02:50:58Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader sin.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sqrt.png 6 320 644 322 2025-01-06T02:51:12Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader sqrt.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader sub.png 6 322 645 324 2025-01-06T02:51:26Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader sub.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Mathematical Shader Processes 0 428 646 431 2025-01-06T02:54:54Z Eric Lengyel 1 wikitext text/x-wiki This is a list of the mathematical shader processes that are available in the [[Shader Editor]] under the Math tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Absolute Value|Shader_abs.png|Value '''A'''|Value of size matching '''A'''|Calculates the absolute value of each component of the input '''A'''.}} |- {{Process|Add|Shader_add.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise sum of the inputs '''A''' and '''B'''.}} |- {{Process|Average|Shader_avg.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise average of the inputs '''A''' and '''B'''.}} |- {{Process|Cosine|Shader_cos.png|Scalar '''A'''|Scalar|Calculates the cosine of the input '''A''', where the input is measured in radians.}} |- {{Process|Cross Product|Shader_xpd.png|3D vectors '''A''' and '''B'''|3D vector|Calculates the cross product of the inputs '''A''' and '''B'''.}} |- {{Process|Divide|Shader_div.png|Value '''A''', Scalar '''B'''|Value of size matching '''A'''|Calculates the quotient of each component of the input '''A''' and the scalar input '''B'''. ''Tip:'' If you're dividing by a constant value, then it would be more efficient to multiply by the reciprocal of the constant. For example, you should multiply by 0.5 instead of dividing by 2.0.}} |- {{Process|Dot Product 3D|Shader_dp3.png|3D vectors '''A''' and '''B'''|Scalar|Calculates the dot product of the inputs '''A''' and '''B'''.}} |- {{Process|Dot Product 4D|Shader_dp4.png|4D vectors '''A''' and '''B'''|Scalar|Calculates the dot product of the inputs '''A''' and '''B'''.}} |- {{Process|Exp Base 2|Shader_ex2.png|Scalar '''A'''|Scalar|Calculates 2 raised to the power given by the input '''A'''.}} |- {{Process|Expand|Shader_expand.png|Value '''A'''|Value of size matching '''A'''|Multiplies each component of the input '''A''' by 2.0 and then subtracts 1.0.}} |- {{Process|Floor|Shader_flr.png|Value '''A'''|Value of size matching '''A'''|Calculates the floor of each component of the input '''A'''. To calculate a ceiling, negate the input and output of the Floor process.}} |- {{Process|Fraction|Shader_frc.png|Value '''A'''|Value of size matching '''A'''|Calculates the fraction of each component of the input '''A'''. The fraction of a number is the difference between that number and its floor.}} |- {{Process|Invert|Shader_invert.png|Value '''A'''|Value of size matching '''A'''|Subtracts each component of the input '''A''' from 1.0.}} |- {{Process|Linear Interpolate|Shader_lrp.png|Values '''A''', '''B''', and '''t'''|Value of size matching largest of '''A''', '''B''', and '''t'''|Calculates the linear interpolation between the components of '''A''' and '''B''' using the components of the input '''t''' as the interpolation parameter.}} |- {{Process|Log Base 2|Shader_lg2.png|Scalar '''A'''|Scalar|Calculates the logarithm base 2 of the input '''A'''. If the input is not positive, then the result is undefined.}} |- {{Process|Magnitude 3D|Shader_magnitude3d.png|3D vector '''A'''|Scalar|Calculates the magnitude of the input '''A'''.}} |- {{Process|Maximum|Shader_max.png|Values '''A''' and '''B''' (required), value '''C''' (optional)|Value of size matching larger of '''A''', '''B''', and '''C'''|Calculates the componentwise maximum of the inputs '''A''', '''B''', and '''C'''. If input '''C''' is omitted, then the maximum of only '''A''' and '''B''' is calculated.}} |- {{Process|Minimum|Shader_min.png|Values '''A''' and '''B''' (required), value '''C''' (optional)|Value of size matching larger of '''A''', '''B''', and '''C'''|Calculates the componentwise minimum of the inputs '''A''', '''B''', and '''C'''. If input '''C''' is omitted, then the minimum of only '''A''' and '''B''' is calculated.}} |- {{Process|Multiply|Shader_mul.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise product of the inputs '''A''' and '''B'''.}} |- {{Process|Multiply Add|Shader_mad.png|Values '''A''', '''B''', and '''C'''|Value of size matching largest of '''A''', '''B''', and '''C'''|Calculates the componentwise product of the inputs '''A''' and '''B''' and then adds the components of the input '''C'''.}} |- {{Process|Normalize 3D|Shader_normalize3d.png|3D vector '''A'''|3D vector|Normalizes the input '''A'''. If the input is the zero vector, then the result is undefined.}} |- {{Process|Power|Shader_pow.png|Scalars '''A''' and '''B'''|Scalar|Calculates the input '''A''' raised to the power of the input '''B'''. If the input '''A''' is negative, then the result is undefined. If the input '''A''' is zero and the input '''B''' is not positive, then the result is undefined. ''Tip:'' If you're just squaring a value, then it would be more efficient to multiply the value by itself. That is, you should calculate '''A'''&nbsp;&times;&nbsp;'''A''' using the '''Multiply''' process instead of raising '''A''' to the power of 2.}} |- {{Process|Reciprocal|Shader_rcp.png|Scalar '''A'''|Scalar|Calculates the reciprocal of the input '''A'''. If the input is zero, then the result is undefined.}} |- {{Process|Reciprocal Square Root|Shader_rsq.png|Scalar '''A'''|Scalar|Calculates the reciprocal square root of the input '''A'''. If the input is not positive, then the result is undefined.}} |- {{Process|Round|Shader_round.png|Value '''A'''|Value of size matching '''A'''|Rounds each component of the input '''A''' to the nearest integer.}} |- {{Process|Saturate|Shader_sat.png|Value '''A'''|Value of size matching '''A'''|Clamps each component of the input '''A''' to the range [0,1].}} |- {{Process|Set if Equal|Shader_seq.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set if Greater Equal|Shader_sge.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is greater than or equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set if Greater Than|Shader_sgt.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is greater than the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set if Less Equal|Shader_sle.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is less than or equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set of Less Than|Shader_slt.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is less than the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set if Not Equal|Shader_sne.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is not equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Sine|Shader_sin.png|Scalar '''A'''|Scalar|Calculates the sine of the input '''A''', where the input is measured in radians.}} |- {{Process|Square Root|Shader_sqrt.png|Scalar '''A'''|Scalar|Calculates the square root of the input '''A'''. If the input is negative, then the result is undefined.}} |- {{Process|Subtract|Shader_sub.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise difference of the inputs '''A''' and '''B'''.}} |- {{Process|Sum of Products|Shader_sumproducts.png|Values '''A''', '''B''', '''C''', and '''D'''|Value of size matching largest of '''A''', '''B''', '''C''', and '''D'''|Calculates the componentwise products of the inputs '''A''' and '''B''' and the componentwise products of the inputs '''C''' and '''D''' and then calculates the componentwise sum of the results.}} |} == See Also == * [[Shader Editor]] * [[Basic Shader Processes]] * [[Complex Shader Processes]] * [[Interpolant Shader Processes]] [[Category:Shaders]] 6e389c82400c3cc287794fe66e49d60b0c9f3711 File:Shader sumproducts.png 6 529 647 2025-01-06T02:55:12Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader ambientoutput.png 6 243 648 245 2025-01-06T03:01:21Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader ambientoutput.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader lightingoutput.png 6 278 649 280 2025-01-06T03:01:36Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader lightingoutput.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader alphaoutput.png 6 241 650 243 2025-01-06T03:01:50Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader alphaoutput.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader alphatestoutput.png 6 242 651 244 2025-01-06T03:02:04Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader alphatestoutput.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader emissionoutput.png 6 257 652 259 2025-01-06T03:02:16Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader emissionoutput.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader glowoutput.png 6 269 653 271 2025-01-06T03:02:28Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader glowoutput.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader bloomoutput.png 6 245 654 247 2025-01-06T03:02:40Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader bloomoutput.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader reflectionoutput.png 6 305 655 307 2025-01-06T03:02:54Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader reflectionoutput.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader refractionoutput.png 6 307 656 309 2025-01-06T03:03:07Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader refractionoutput.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader environmentoutput.png 6 258 657 260 2025-01-06T03:03:23Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader environmentoutput.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader terrainenvironmentoutput.png 6 328 658 330 2025-01-06T03:06:12Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader terrainenvironmentoutput.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Shader Editor 0 424 659 427 2025-01-06T03:06:16Z Eric Lengyel 1 /* Output Processes */ wikitext text/x-wiki __NOTOC__ There are two ways to create materials in the C4 Engine. The first method is to simply configure a set of predefined attributes in the [[Material Editor]]. This is the easiest and fastest way to create a new material, and most ordinary materials can be made using only those attributes. A more advanced method is to use the Shader Editor to define the exact calculations used by the engine to render a material. The Shader Editor provides you with the power to create a limitless variety of materials within the context of a graphical interface. == Opening the Shader Editor == [[File:Shadereditor.png|right|frame|'''Figure 1.''' The Shader Editor window.]] The image to the right shows the Shader Editor. The Shader Editor is opened from inside the [[Material Editor]] by choosing '''Edit Shader''' from the '''Material''' menu. If the selected material already had conventional attributes assigned to it through the settings in the Material Editor, then the Shader Editor will initially show a translation of those attributes into the shader graph. If the selected material was empty (because no settings had been specified for it yet), then the Shader Editor will initially show default graph with a minimal number of nodes. == Shader Graphs == A shader is represented in the Shader Editor by what is known as a ''data flow graph''. The nodes in this graph are called ''processes'', and the edges in this graph are called ''routes''. A shader is a special type of graph called a ''directed acyclic graph'', or ''DAG'', meaning that data flows in a specific direction from one process to another and there are no loops. Each box in the shader graph represents a single process. A process can be a simple mathematical operation, a constant input value such as a color, an interpolated value such as the direction to the light source, or a more complex operation defined by the engine such as a parallax offset calculation. A route is a directed edge shown as a curve with an arrowhead at one end, and it represents the flow of data from one process to another. Routes begin at one process and end at a ''port'' belonging to another process. Every process has between zero and four ports, and each can be occupied by only one incoming route at a time. Ports with a plain background are required, and ports with a striped background are optional. All required ports must have an incoming route attached to them in order for the shader to be valid. == Editing a Shader == The tabbed lists on the left side of the Shader Editor show the processes that are available for use in a shader. They are divided into four categories that are described in more detail below: Basic, Math, Complex, and Interpolants. A new process is added to a shader by selecting it in the list and then clicking in the viewport. The editor won't let you place two processes on top of each other, and the cursor will change to indicate where it's possible to place a new process. Routes are added to a shader by clicking inside the circle on the right side of a process and dragging into a port belonging to another process. This causes a new route to be created beginning at the process you clicked on and ending at the input port to which you dragged. If a port is already occupied by another route, then the existing route is deleted and replaced with the new route that you are creating. You cannot connect a route from one process to a port belonging to any other process preceding that process in the graph because it would create a cycle. The physical position of a process in the viewport is irrelevant. The data flow structure of a shader is determined entirely by the route connections. Processes may be placed in any convenient location. == Processes == A process takes between zero and four inputs and produces at most a single output. The output may be sent to any number of input ports for other processes. For many types of processes, the process box shown in the Shader Editor displays additional information. For example, the Texture Map process shows a small image of the texture map, and the Constant Vector process shows the four constant values that it outputs. Most mathematical operations display a mathematical expression showing exactly how their input values are used to calculate an output value. Double-clicking on a process, or selecting a process and typing Ctrl-I, opens the Process Info window for that process. In the Process Info window, every process has a comment field that let's you specify some text that is displayed at the bottom of the process box in the Shader Editor. Some processes also have extra settings that appear in the Process Info window. Each type of process available for use in a shader is described individually on the following pages (corresponding to the groups displayed in the Shader Editor): * [[Basic Shader Processes | List of basic processes]] * [[Mathematical Shader Processes | List of mathematical processes]] * [[Complex Shader Processes | List of complex processes]] * [[Interpolant Shader Processes | List of interpolant processes]] == Routes == The routes in a shader graph carry data from one process to another. Each route can carry between one and four floating-point values&mdash;the actual number is determined by the output size of the route's start process. A swizzle and negation may be applied to a route. These can be set by double-clicking on a route or by selecting a route and typing Ctrl-I. By default, the swizzle for a route is <code>xyzw</code>, meaning that there is no change to the order of the components. If any other swizzle is specified, or the values are negated, then that information is displayed in a small box at the center of the path representing the route. The swizzle may be specified using any letters from the sets <code>xyzw</code>, <code>rgba</code>, or <code>stpq</code>. Specifying only a single letter is shorthand for the same letter repeated four times. For example, the swizzle <code>z</code> is equivalent to the swizzle <code>zzzz</code>. If a route carries fewer than four components, then each component specified in its swizzle is clamped to the last available component. For example, if a route carries only three components, then any <code>w</code>, <code>a</code>, or <code>q</code> in the swizzle ultimately interpreted as the third component of the data carried by the route. The swizzle <code>wxyz</code> would really mean <code>zxyz</code>. This is particularly important in the case that two routes of different sizes are used as inputs to a binary operation. The operation is performed using the number of components for larger of the two routes, so the missing components of the smaller route are taken from the components specified by the clamped swizzle. == Shader Editor Tools == There are four tool buttons in the upper-left corner of the Shader Editor window, and they have the following uses. In addition to clicking on the tool button, each of these tools can also be selected by pressing the shortcut number key as shown in the table. (The shortcuts were chosen to be the same as the corresponding tools in the World Editor.) {| {{Table}} {{Tablehead3|Icon|Shortcut|Function}} |- {{Tablerow3|[[File:Tool_select.png]]|1|'''Select / Move'''. Selects a process or route in a shader. Clicking outside of a process and dragging will create a box that selects all of the processes inside it. Clicking inside a process and dragging moves all of the currently selected processes. (When processes are moved, they are automatically prevented from moving on top of other processes.)}} |- {{Tablerow3|[[File:Tool_scroll.png]]|6|'''Scroll'''. Scrolls the shader viewport. Holding the Alt key with any other tool temporarily selects the scroll tool.}} |- {{Tablerow3|[[File:Tool_zoom.png]]|7|'''Zoom'''. Changes the scale of the shader viewport. Using the mouse wheel with any other tool also zooms.}} |- {{Tablerow3|[[File:Tool_section.png]]||'''Draw Section'''. Draws a rectangular box with a title bar behind all processes in the graph. This can be used to visually organize groups of processes in a shader.}} |} == Output Processes == Each shader graph contains a set of ''output processes'' that represent the final values produced by the shader. These are colored green in the shader editor, they cannot be deleted, and they can have no output routes. The only output process that has a required input port is the '''Ambient Reflection Output''' process. All other output processes have only optional input ports and are ignored if they are not used. The individual output processes are described in the following table. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Ambient&nbsp;Reflection&nbsp;Output|Shader_ambientoutput.png|RGB color '''RGB''' (required), Normal '''N''' (optional)|None|This is the primary output process for the ambient shader. The color sent to this output process is combined with the ambient lighting environment to produce the final ambient light reflection for a material. The normal vector '''N''' is currently unused, but will be important in future ambient lighting models.}} |- {{Process|Light&nbsp;Reflection&nbsp;Output|Shader_lightingoutput.png|RGB color '''RGB''' (optional), Impostor depth '''Z''' (optional)|None|This is the primary output process for the light shader. The color sent to this output process is combined with the color from a light source to produce the final light reflection for a material. In an impostor shader, the alpha channel of the output of the Impostor Normal process should be sent to the '''Z''' input port to provide the impostor depth.}} |- {{Process|Alpha&nbsp;Output|Shader_alphaoutput.png|Scalar '''A''' (optional)|None|If a material is transparent, then the alpha value sent to this output process controls the transparency. This is currently useful only for objects rendered in the effect pass. If the Glow Output process is used, then the Alpha Output process is ignored.}} |- {{Process|Alpha&nbsp;Test&nbsp;Output|Shader_alphatestoutput.png|Scalar '''A''' (optional)|None|If a material uses the alpha test, then the value sent to this output process is the value that is tested. The material must have the alpha test flag set in the Material Manager for this output process to be used.}} |- {{Process|Emission&nbsp;Output|Shader_emissionoutput.png|RGB color '''RGB''' (optional)|None|The color sent to this output process is added to the final ambient color as an emission term.}} |- {{Process|Glow&nbsp;Output|Shader_glowoutput.png|Scalar '''A''' (optional)|None|If a material uses emission glow, then the value sent to this output process determines the glow intensity. The material must have the emission glow flag set in the Material Manager for this output process to be used. If the alpha test flag is set, then the Glow Output process is ignored.}} |- {{Process|Bloom&nbsp;Output|Shader_bloomoutput.png|Scalar '''A''' (optional)|None|If a material uses specular bloom, then the value sent to this output process determines the bloom intensity. The material must have the specular bloom flag set in the Material Manager for this output process to be used.}} |- {{Process|Reflection&nbsp;Buffer&nbsp;Output|Shader_reflectionoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the reflection buffer is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the reflection. Normal incidence reflectivity and bump offset scale can be configured in the settings for the process.}} |- {{Process|Refraction&nbsp;Buffer&nbsp;Output|Shader_refractionoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the refraction buffer is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the refraction. The bump offset scale can be configured in the settings for the process.}} |- {{Process|Environment&nbsp;Output|Shader_environmentoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process.}} |- {{Process|Terrain&nbsp;Environment&nbsp;Output|Shader_terrainenvironmentoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. Terrain normal vectors may be sent to the '''N1''', '''N2''', and '''N3''' input port in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process.}} |} == See Also == * [[Material Editor]] [[Category:Shaders]] d35209adbef4ba17d06a167cf65eaa3791218e84 661 659 2025-01-06T03:11:26Z Eric Lengyel 1 /* Output Processes */ wikitext text/x-wiki __NOTOC__ There are two ways to create materials in the C4 Engine. The first method is to simply configure a set of predefined attributes in the [[Material Editor]]. This is the easiest and fastest way to create a new material, and most ordinary materials can be made using only those attributes. A more advanced method is to use the Shader Editor to define the exact calculations used by the engine to render a material. The Shader Editor provides you with the power to create a limitless variety of materials within the context of a graphical interface. == Opening the Shader Editor == [[File:Shadereditor.png|right|frame|'''Figure 1.''' The Shader Editor window.]] The image to the right shows the Shader Editor. The Shader Editor is opened from inside the [[Material Editor]] by choosing '''Edit Shader''' from the '''Material''' menu. If the selected material already had conventional attributes assigned to it through the settings in the Material Editor, then the Shader Editor will initially show a translation of those attributes into the shader graph. If the selected material was empty (because no settings had been specified for it yet), then the Shader Editor will initially show default graph with a minimal number of nodes. == Shader Graphs == A shader is represented in the Shader Editor by what is known as a ''data flow graph''. The nodes in this graph are called ''processes'', and the edges in this graph are called ''routes''. A shader is a special type of graph called a ''directed acyclic graph'', or ''DAG'', meaning that data flows in a specific direction from one process to another and there are no loops. Each box in the shader graph represents a single process. A process can be a simple mathematical operation, a constant input value such as a color, an interpolated value such as the direction to the light source, or a more complex operation defined by the engine such as a parallax offset calculation. A route is a directed edge shown as a curve with an arrowhead at one end, and it represents the flow of data from one process to another. Routes begin at one process and end at a ''port'' belonging to another process. Every process has between zero and four ports, and each can be occupied by only one incoming route at a time. Ports with a plain background are required, and ports with a striped background are optional. All required ports must have an incoming route attached to them in order for the shader to be valid. == Editing a Shader == The tabbed lists on the left side of the Shader Editor show the processes that are available for use in a shader. They are divided into four categories that are described in more detail below: Basic, Math, Complex, and Interpolants. A new process is added to a shader by selecting it in the list and then clicking in the viewport. The editor won't let you place two processes on top of each other, and the cursor will change to indicate where it's possible to place a new process. Routes are added to a shader by clicking inside the circle on the right side of a process and dragging into a port belonging to another process. This causes a new route to be created beginning at the process you clicked on and ending at the input port to which you dragged. If a port is already occupied by another route, then the existing route is deleted and replaced with the new route that you are creating. You cannot connect a route from one process to a port belonging to any other process preceding that process in the graph because it would create a cycle. The physical position of a process in the viewport is irrelevant. The data flow structure of a shader is determined entirely by the route connections. Processes may be placed in any convenient location. == Processes == A process takes between zero and four inputs and produces at most a single output. The output may be sent to any number of input ports for other processes. For many types of processes, the process box shown in the Shader Editor displays additional information. For example, the Texture Map process shows a small image of the texture map, and the Constant Vector process shows the four constant values that it outputs. Most mathematical operations display a mathematical expression showing exactly how their input values are used to calculate an output value. Double-clicking on a process, or selecting a process and typing Ctrl-I, opens the Process Info window for that process. In the Process Info window, every process has a comment field that let's you specify some text that is displayed at the bottom of the process box in the Shader Editor. Some processes also have extra settings that appear in the Process Info window. Each type of process available for use in a shader is described individually on the following pages (corresponding to the groups displayed in the Shader Editor): * [[Basic Shader Processes | List of basic processes]] * [[Mathematical Shader Processes | List of mathematical processes]] * [[Complex Shader Processes | List of complex processes]] * [[Interpolant Shader Processes | List of interpolant processes]] == Routes == The routes in a shader graph carry data from one process to another. Each route can carry between one and four floating-point values&mdash;the actual number is determined by the output size of the route's start process. A swizzle and negation may be applied to a route. These can be set by double-clicking on a route or by selecting a route and typing Ctrl-I. By default, the swizzle for a route is <code>xyzw</code>, meaning that there is no change to the order of the components. If any other swizzle is specified, or the values are negated, then that information is displayed in a small box at the center of the path representing the route. The swizzle may be specified using any letters from the sets <code>xyzw</code>, <code>rgba</code>, or <code>stpq</code>. Specifying only a single letter is shorthand for the same letter repeated four times. For example, the swizzle <code>z</code> is equivalent to the swizzle <code>zzzz</code>. If a route carries fewer than four components, then each component specified in its swizzle is clamped to the last available component. For example, if a route carries only three components, then any <code>w</code>, <code>a</code>, or <code>q</code> in the swizzle ultimately interpreted as the third component of the data carried by the route. The swizzle <code>wxyz</code> would really mean <code>zxyz</code>. This is particularly important in the case that two routes of different sizes are used as inputs to a binary operation. The operation is performed using the number of components for larger of the two routes, so the missing components of the smaller route are taken from the components specified by the clamped swizzle. == Shader Editor Tools == There are four tool buttons in the upper-left corner of the Shader Editor window, and they have the following uses. In addition to clicking on the tool button, each of these tools can also be selected by pressing the shortcut number key as shown in the table. (The shortcuts were chosen to be the same as the corresponding tools in the World Editor.) {| {{Table}} {{Tablehead3|Icon|Shortcut|Function}} |- {{Tablerow3|[[File:Tool_select.png]]|1|'''Select / Move'''. Selects a process or route in a shader. Clicking outside of a process and dragging will create a box that selects all of the processes inside it. Clicking inside a process and dragging moves all of the currently selected processes. (When processes are moved, they are automatically prevented from moving on top of other processes.)}} |- {{Tablerow3|[[File:Tool_scroll.png]]|6|'''Scroll'''. Scrolls the shader viewport. Holding the Alt key with any other tool temporarily selects the scroll tool.}} |- {{Tablerow3|[[File:Tool_zoom.png]]|7|'''Zoom'''. Changes the scale of the shader viewport. Using the mouse wheel with any other tool also zooms.}} |- {{Tablerow3|[[File:Tool_section.png]]||'''Draw Section'''. Draws a rectangular box with a title bar behind all processes in the graph. This can be used to visually organize groups of processes in a shader.}} |} == Output Processes == Each shader graph contains a set of ''output processes'' that represent the final values produced by the shader. These are colored green in the shader editor, they cannot be deleted, and they can have no output routes. The only output process that has a required input port is the '''Ambient Reflection Output''' process. All other output processes have only optional input ports and are ignored if they are not used. The individual output processes are described in the following table. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Ambient&nbsp;Reflection&nbsp;Output|Shader_ambientoutput.png|RGB color '''RGB''' (required), Normal '''N''' (optional)|None|This is the primary output process for the ambient shader. The color sent to this output process is combined with the ambient lighting environment to produce the final ambient light reflection for a material. The normal vector '''N''' is currently unused, but will be important in future ambient lighting models.}} |- {{Process|Light&nbsp;Reflection&nbsp;Output|Shader_lightingoutput.png|RGB color '''RGB''' (optional), Impostor depth '''Z''' (optional)|None|This is the primary output process for the light shader. The color sent to this output process is combined with the color from a light source to produce the final light reflection for a material. In an impostor shader, the alpha channel of the output of the Impostor Normal process should be sent to the '''Z''' input port to provide the impostor depth.}} |- {{Process|Alpha&nbsp;Output|Shader_alphaoutput.png|Scalar '''A''' (optional)|None|If a material is transparent, then the alpha value sent to this output process controls the transparency. This is currently useful only for objects rendered in the effect pass. If the Glow Output process is used, then the Alpha Output process is ignored.}} |- {{Process|Alpha&nbsp;Test&nbsp;Output|Shader_alphatestoutput.png|Scalar '''A''' (optional)|None|If a material uses the alpha test, then the value sent to this output process is the value that is tested. The material must have the alpha test flag set in the Material Manager for this output process to be used.}} |- {{Process|Emission&nbsp;Output|Shader_emissionoutput.png|RGB color '''RGB''' (optional)|None|The color sent to this output process is added to the final ambient color as an emission term.}} |- {{Process|Glow&nbsp;Output|Shader_glowoutput.png|Scalar '''A''' (optional)|None|If a material uses emission glow, then the value sent to this output process determines the glow intensity. The material must have the emission glow flag set in the Material Manager for this output process to be used. If the alpha test flag is set, then the Glow Output process is ignored.}} |- {{Process|Bloom&nbsp;Output|Shader_bloomoutput.png|Scalar '''A''' (optional)|None|If a material uses specular bloom, then the value sent to this output process determines the bloom intensity. The material must have the specular bloom flag set in the Material Manager for this output process to be used.}} |- {{Process|Reflection&nbsp;Buffer&nbsp;Output|Shader_reflectionoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the reflection buffer is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the reflection. Normal incidence reflectivity and bump offset scale can be configured in the settings for the process.}} |- {{Process|Refraction&nbsp;Buffer&nbsp;Output|Shader_refractionoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the refraction buffer is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the refraction. The bump offset scale can be configured in the settings for the process.}} |- {{Process|Environment&nbsp;Output|Shader_environmentoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional), scalar '''BIAS''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process. If the '''BIAS''' input is connected, then it's value is added to the mipmap index calculated by the hardware.}} |- {{Process|Terrain&nbsp;Environment&nbsp;Output|Shader_terrainenvironmentoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. Terrain normal vectors may be sent to the '''N'''<sub>1</sub>, '''N'''<sub>2</sub>, and '''N'''<sub>3</sub> input ports in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process.}} |} == See Also == * [[Material Editor]] [[Category:Shaders]] dbb2c477376246efe25df8169f60d005a9a7de0d 672 661 2025-01-06T04:18:12Z Eric Lengyel 1 /* Output Processes */ wikitext text/x-wiki __NOTOC__ There are two ways to create materials in the C4 Engine. The first method is to simply configure a set of predefined attributes in the [[Material Editor]]. This is the easiest and fastest way to create a new material, and most ordinary materials can be made using only those attributes. A more advanced method is to use the Shader Editor to define the exact calculations used by the engine to render a material. The Shader Editor provides you with the power to create a limitless variety of materials within the context of a graphical interface. == Opening the Shader Editor == [[File:Shadereditor.png|right|frame|'''Figure 1.''' The Shader Editor window.]] The image to the right shows the Shader Editor. The Shader Editor is opened from inside the [[Material Editor]] by choosing '''Edit Shader''' from the '''Material''' menu. If the selected material already had conventional attributes assigned to it through the settings in the Material Editor, then the Shader Editor will initially show a translation of those attributes into the shader graph. If the selected material was empty (because no settings had been specified for it yet), then the Shader Editor will initially show default graph with a minimal number of nodes. == Shader Graphs == A shader is represented in the Shader Editor by what is known as a ''data flow graph''. The nodes in this graph are called ''processes'', and the edges in this graph are called ''routes''. A shader is a special type of graph called a ''directed acyclic graph'', or ''DAG'', meaning that data flows in a specific direction from one process to another and there are no loops. Each box in the shader graph represents a single process. A process can be a simple mathematical operation, a constant input value such as a color, an interpolated value such as the direction to the light source, or a more complex operation defined by the engine such as a parallax offset calculation. A route is a directed edge shown as a curve with an arrowhead at one end, and it represents the flow of data from one process to another. Routes begin at one process and end at a ''port'' belonging to another process. Every process has between zero and four ports, and each can be occupied by only one incoming route at a time. Ports with a plain background are required, and ports with a striped background are optional. All required ports must have an incoming route attached to them in order for the shader to be valid. == Editing a Shader == The tabbed lists on the left side of the Shader Editor show the processes that are available for use in a shader. They are divided into four categories that are described in more detail below: Basic, Math, Complex, and Interpolants. A new process is added to a shader by selecting it in the list and then clicking in the viewport. The editor won't let you place two processes on top of each other, and the cursor will change to indicate where it's possible to place a new process. Routes are added to a shader by clicking inside the circle on the right side of a process and dragging into a port belonging to another process. This causes a new route to be created beginning at the process you clicked on and ending at the input port to which you dragged. If a port is already occupied by another route, then the existing route is deleted and replaced with the new route that you are creating. You cannot connect a route from one process to a port belonging to any other process preceding that process in the graph because it would create a cycle. The physical position of a process in the viewport is irrelevant. The data flow structure of a shader is determined entirely by the route connections. Processes may be placed in any convenient location. == Processes == A process takes between zero and four inputs and produces at most a single output. The output may be sent to any number of input ports for other processes. For many types of processes, the process box shown in the Shader Editor displays additional information. For example, the Texture Map process shows a small image of the texture map, and the Constant Vector process shows the four constant values that it outputs. Most mathematical operations display a mathematical expression showing exactly how their input values are used to calculate an output value. Double-clicking on a process, or selecting a process and typing Ctrl-I, opens the Process Info window for that process. In the Process Info window, every process has a comment field that let's you specify some text that is displayed at the bottom of the process box in the Shader Editor. Some processes also have extra settings that appear in the Process Info window. Each type of process available for use in a shader is described individually on the following pages (corresponding to the groups displayed in the Shader Editor): * [[Basic Shader Processes | List of basic processes]] * [[Mathematical Shader Processes | List of mathematical processes]] * [[Complex Shader Processes | List of complex processes]] * [[Interpolant Shader Processes | List of interpolant processes]] == Routes == The routes in a shader graph carry data from one process to another. Each route can carry between one and four floating-point values&mdash;the actual number is determined by the output size of the route's start process. A swizzle and negation may be applied to a route. These can be set by double-clicking on a route or by selecting a route and typing Ctrl-I. By default, the swizzle for a route is <code>xyzw</code>, meaning that there is no change to the order of the components. If any other swizzle is specified, or the values are negated, then that information is displayed in a small box at the center of the path representing the route. The swizzle may be specified using any letters from the sets <code>xyzw</code>, <code>rgba</code>, or <code>stpq</code>. Specifying only a single letter is shorthand for the same letter repeated four times. For example, the swizzle <code>z</code> is equivalent to the swizzle <code>zzzz</code>. If a route carries fewer than four components, then each component specified in its swizzle is clamped to the last available component. For example, if a route carries only three components, then any <code>w</code>, <code>a</code>, or <code>q</code> in the swizzle ultimately interpreted as the third component of the data carried by the route. The swizzle <code>wxyz</code> would really mean <code>zxyz</code>. This is particularly important in the case that two routes of different sizes are used as inputs to a binary operation. The operation is performed using the number of components for larger of the two routes, so the missing components of the smaller route are taken from the components specified by the clamped swizzle. == Shader Editor Tools == There are four tool buttons in the upper-left corner of the Shader Editor window, and they have the following uses. In addition to clicking on the tool button, each of these tools can also be selected by pressing the shortcut number key as shown in the table. (The shortcuts were chosen to be the same as the corresponding tools in the World Editor.) {| {{Table}} {{Tablehead3|Icon|Shortcut|Function}} |- {{Tablerow3|[[File:Tool_select.png]]|1|'''Select / Move'''. Selects a process or route in a shader. Clicking outside of a process and dragging will create a box that selects all of the processes inside it. Clicking inside a process and dragging moves all of the currently selected processes. (When processes are moved, they are automatically prevented from moving on top of other processes.)}} |- {{Tablerow3|[[File:Tool_scroll.png]]|6|'''Scroll'''. Scrolls the shader viewport. Holding the Alt key with any other tool temporarily selects the scroll tool.}} |- {{Tablerow3|[[File:Tool_zoom.png]]|7|'''Zoom'''. Changes the scale of the shader viewport. Using the mouse wheel with any other tool also zooms.}} |- {{Tablerow3|[[File:Tool_section.png]]||'''Draw Section'''. Draws a rectangular box with a title bar behind all processes in the graph. This can be used to visually organize groups of processes in a shader.}} |} == Output Processes == Each shader graph contains a set of ''output processes'' that represent the final values produced by the shader. These are colored green in the shader editor, they cannot be deleted, and they can have no output routes. The only output process that has a required input port is the '''Ambient Reflection Output''' process. All other output processes have only optional input ports and are ignored if they are not used. The individual output processes are described in the following table. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Ambient&nbsp;Reflection&nbsp;Output|Shader_ambientoutput.png|RGB color '''RGB''' (required), World-space or tangent-space normal '''N''' (optional)|None|This is the primary output process for the ambient shader. The color sent to this output process is combined with the ambient lighting environment to produce the final ambient light reflection for a material.}} |- {{Process|Light&nbsp;Reflection&nbsp;Output|Shader_lightingoutput.png|RGB color '''RGB''' (optional), Impostor depth '''Z''' (optional)|None|This is the primary output process for the light shader. The color sent to this output process is combined with the color from a light source to produce the final light reflection for a material. In an impostor shader, the alpha channel of the output of the Impostor Normal process should be sent to the '''Z''' input port to provide the impostor depth.}} |- {{Process|Alpha&nbsp;Output|Shader_alphaoutput.png|Scalar '''A''' (optional)|None|If a material is transparent, then the alpha value sent to this output process controls the transparency. This is currently useful only for objects rendered in the effect pass. If the Glow Output process is used, then the Alpha Output process is ignored.}} |- {{Process|Alpha&nbsp;Test&nbsp;Output|Shader_alphatestoutput.png|Scalar '''A''' (optional)|None|If a material uses the alpha test, then the value sent to this output process is the value that is tested. The material must have the alpha test flag set in the Material Manager for this output process to be used.}} |- {{Process|Emission&nbsp;Output|Shader_emissionoutput.png|RGB color '''RGB''' (optional)|None|The color sent to this output process is added to the final ambient color as an emission term.}} |- {{Process|Glow&nbsp;Output|Shader_glowoutput.png|Scalar '''A''' (optional)|None|If a material uses emission glow, then the value sent to this output process determines the glow intensity. The material must have the emission glow flag set in the Material Manager for this output process to be used. If the alpha test flag is set, then the Glow Output process is ignored.}} |- {{Process|Bloom&nbsp;Output|Shader_bloomoutput.png|Scalar '''A''' (optional)|None|If a material uses specular bloom, then the value sent to this output process determines the bloom intensity. The material must have the specular bloom flag set in the Material Manager for this output process to be used.}} |- {{Process|Reflection&nbsp;Buffer&nbsp;Output|Shader_reflectionoutput.png|RGB color '''RGB''' (optional), World-space or tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the reflection buffer is multiplied by the input color and added to the final ambient color. A normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the reflection. Normal incidence reflectivity and bump offset scale can be configured in the settings for the process.}} |- {{Process|Refraction&nbsp;Buffer&nbsp;Output|Shader_refractionoutput.png|RGB color '''RGB''' (optional), World-space or tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the refraction buffer is multiplied by the input color and added to the final ambient color. A normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the refraction. The bump offset scale can be configured in the settings for the process.}} |- {{Process|Environment&nbsp;Output|Shader_environmentoutput.png|RGB color '''RGB''' (optional), World-space or tangent-space normal vector '''N''' (optional), scalar '''BIAS''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. A normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process. If the '''BIAS''' input is connected, then it's value is added to the mipmap index calculated by the hardware.}} |- {{Process|Terrain&nbsp;Environment&nbsp;Output|Shader_terrainenvironmentoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. Terrain normal vectors may be sent to the '''N'''<sub>1</sub>, '''N'''<sub>2</sub>, and '''N'''<sub>3</sub> input ports in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process.}} |} == See Also == * [[Material Editor]] [[Category:Shaders]] d91b3df15f4705af3736be0cfe80b14572b3e03b 674 672 2025-01-06T04:31:16Z Eric Lengyel 1 wikitext text/x-wiki __NOTOC__ There are two ways to create materials in the C4 Engine. The first method is to simply configure a set of predefined attributes in the [[Material Editor]]. This is the easiest and fastest way to create a new material, and most ordinary materials can be made using only those attributes. A more advanced method is to use the Shader Editor to define the exact calculations used by the engine to render a material. The Shader Editor provides you with the power to create a limitless variety of materials within the context of a graphical interface. == Opening the Shader Editor == The image to below shows the Shader Editor. The Shader Editor is opened from inside the [[Material Editor]] by choosing '''Edit Shader''' from the '''Material''' menu. If the selected material already had conventional attributes assigned to it through the settings in the Material Editor, then the Shader Editor will initially show a translation of those attributes into the shader graph. If the selected material was empty (because no settings had been specified for it yet), then the Shader Editor will initially show default graph with a minimal number of nodes. [[File:Shadereditor.png]] == Shader Graphs == A shader is represented in the Shader Editor by what is known as a ''data flow graph''. The nodes in this graph are called ''processes'', and the edges in this graph are called ''routes''. A shader is a special type of graph called a ''directed acyclic graph'', or ''DAG'', meaning that data flows in a specific direction from one process to another and there are no loops. Each box in the shader graph represents a single process. A process can be a simple mathematical operation, a constant input value such as a color, an interpolated value such as the direction to the light source, or a more complex operation defined by the engine such as a parallax offset calculation. A route is a directed edge shown as a curve with an arrowhead at one end, and it represents the flow of data from one process to another. Routes begin at one process and end at a ''port'' belonging to another process. Every process has between zero and four ports, and each can be occupied by only one incoming route at a time. Ports with a plain background are required, and ports with a striped background are optional. All required ports must have an incoming route attached to them in order for the shader to be valid. == Editing a Shader == The tabbed lists on the left side of the Shader Editor show the processes that are available for use in a shader. They are divided into four categories that are described in more detail below: Basic, Math, Complex, and Interpolants. A new process is added to a shader by selecting it in the list and then clicking in the viewport. The editor won't let you place two processes on top of each other, and the cursor will change to indicate where it's possible to place a new process. Routes are added to a shader by clicking inside the circle on the right side of a process and dragging into a port belonging to another process. This causes a new route to be created beginning at the process you clicked on and ending at the input port to which you dragged. If a port is already occupied by another route, then the existing route is deleted and replaced with the new route that you are creating. You cannot connect a route from one process to a port belonging to any other process preceding that process in the graph because it would create a cycle. The physical position of a process in the viewport is irrelevant. The data flow structure of a shader is determined entirely by the route connections. Processes may be placed in any convenient location. == Processes == A process takes between zero and four inputs and produces at most a single output. The output may be sent to any number of input ports for other processes. For many types of processes, the process box shown in the Shader Editor displays additional information. For example, the Texture Map process shows a small image of the texture map, and the Constant Vector process shows the four constant values that it outputs. Most mathematical operations display a mathematical expression showing exactly how their input values are used to calculate an output value. Double-clicking on a process, or selecting a process and typing Ctrl-I, opens the Process Info window for that process. In the Process Info window, every process has a comment field that let's you specify some text that is displayed at the bottom of the process box in the Shader Editor. Some processes also have extra settings that appear in the Process Info window. Each type of process available for use in a shader is described individually on the following pages (corresponding to the groups displayed in the Shader Editor): * [[Basic Shader Processes | List of basic processes]] * [[Mathematical Shader Processes | List of mathematical processes]] * [[Complex Shader Processes | List of complex processes]] * [[Interpolant Shader Processes | List of interpolant processes]] == Routes == The routes in a shader graph carry data from one process to another. Each route can carry between one and four floating-point values&mdash;the actual number is determined by the output size of the route's start process. A swizzle and negation may be applied to a route. These can be set by double-clicking on a route or by selecting a route and typing Ctrl-I. By default, the swizzle for a route is <code>xyzw</code>, meaning that there is no change to the order of the components. If any other swizzle is specified, or the values are negated, then that information is displayed in a small box at the center of the path representing the route. The swizzle may be specified using any letters from the sets <code>xyzw</code>, <code>rgba</code>, or <code>stpq</code>. Specifying only a single letter is shorthand for the same letter repeated four times. For example, the swizzle <code>z</code> is equivalent to the swizzle <code>zzzz</code>. If a route carries fewer than four components, then each component specified in its swizzle is clamped to the last available component. For example, if a route carries only three components, then any <code>w</code>, <code>a</code>, or <code>q</code> in the swizzle ultimately interpreted as the third component of the data carried by the route. The swizzle <code>wxyz</code> would really mean <code>zxyz</code>. This is particularly important in the case that two routes of different sizes are used as inputs to a binary operation. The operation is performed using the number of components for larger of the two routes, so the missing components of the smaller route are taken from the components specified by the clamped swizzle. == Shader Editor Tools == There are four tool buttons in the upper-left corner of the Shader Editor window, and they have the following uses. In addition to clicking on the tool button, each of these tools can also be selected by pressing the shortcut number key as shown in the table. (The shortcuts were chosen to be the same as the corresponding tools in the World Editor.) {| {{Table}} {{Tablehead3|Icon|Shortcut|Function}} |- {{Tablerow3|[[File:Tool_select.png]]|1|'''Select / Move'''. Selects a process or route in a shader. Clicking outside of a process and dragging will create a box that selects all of the processes inside it. Clicking inside a process and dragging moves all of the currently selected processes. (When processes are moved, they are automatically prevented from moving on top of other processes.)}} |- {{Tablerow3|[[File:Tool_scroll.png]]|6|'''Scroll'''. Scrolls the shader viewport. Holding the Alt key with any other tool temporarily selects the scroll tool.}} |- {{Tablerow3|[[File:Tool_zoom.png]]|7|'''Zoom'''. Changes the scale of the shader viewport. Using the mouse wheel with any other tool also zooms.}} |- {{Tablerow3|[[File:Tool_section.png]]||'''Draw Section'''. Draws a rectangular box with a title bar behind all processes in the graph. This can be used to visually organize groups of processes in a shader.}} |} == Output Processes == Each shader graph contains a set of ''output processes'' that represent the final values produced by the shader. These are colored green in the shader editor, they cannot be deleted, and they can have no output routes. The only output process that has a required input port is the '''Ambient Reflection Output''' process. All other output processes have only optional input ports and are ignored if they are not used. The individual output processes are described in the following table. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Ambient&nbsp;Reflection&nbsp;Output|Shader_ambientoutput.png|RGB color '''RGB''' (required), World-space or tangent-space normal '''N''' (optional)|None|This is the primary output process for the ambient shader. The color sent to this output process is combined with the ambient lighting environment to produce the final ambient light reflection for a material.}} |- {{Process|Light&nbsp;Reflection&nbsp;Output|Shader_lightingoutput.png|RGB color '''RGB''' (optional), Impostor depth '''Z''' (optional)|None|This is the primary output process for the light shader. The color sent to this output process is combined with the color from a light source to produce the final light reflection for a material. In an impostor shader, the alpha channel of the output of the Impostor Normal process should be sent to the '''Z''' input port to provide the impostor depth.}} |- {{Process|Alpha&nbsp;Output|Shader_alphaoutput.png|Scalar '''A''' (optional)|None|If a material is transparent, then the alpha value sent to this output process controls the transparency. This is currently useful only for objects rendered in the effect pass. If the Glow Output process is used, then the Alpha Output process is ignored.}} |- {{Process|Alpha&nbsp;Test&nbsp;Output|Shader_alphatestoutput.png|Scalar '''A''' (optional)|None|If a material uses the alpha test, then the value sent to this output process is the value that is tested. The material must have the alpha test flag set in the Material Manager for this output process to be used.}} |- {{Process|Emission&nbsp;Output|Shader_emissionoutput.png|RGB color '''RGB''' (optional)|None|The color sent to this output process is added to the final ambient color as an emission term.}} |- {{Process|Glow&nbsp;Output|Shader_glowoutput.png|Scalar '''A''' (optional)|None|If a material uses emission glow, then the value sent to this output process determines the glow intensity. The material must have the emission glow flag set in the Material Manager for this output process to be used. If the alpha test flag is set, then the Glow Output process is ignored.}} |- {{Process|Bloom&nbsp;Output|Shader_bloomoutput.png|Scalar '''A''' (optional)|None|If a material uses specular bloom, then the value sent to this output process determines the bloom intensity. The material must have the specular bloom flag set in the Material Manager for this output process to be used.}} |- {{Process|Reflection&nbsp;Buffer&nbsp;Output|Shader_reflectionoutput.png|RGB color '''RGB''' (optional), World-space or tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the reflection buffer is multiplied by the input color and added to the final ambient color. A normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the reflection. Normal incidence reflectivity and bump offset scale can be configured in the settings for the process.}} |- {{Process|Refraction&nbsp;Buffer&nbsp;Output|Shader_refractionoutput.png|RGB color '''RGB''' (optional), World-space or tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the refraction buffer is multiplied by the input color and added to the final ambient color. A normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the refraction. The bump offset scale can be configured in the settings for the process.}} |- {{Process|Environment&nbsp;Output|Shader_environmentoutput.png|RGB color '''RGB''' (optional), World-space or tangent-space normal vector '''N''' (optional), scalar '''BIAS''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. A normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process. If the '''BIAS''' input is connected, then it's value is added to the mipmap index calculated by the hardware.}} |- {{Process|Terrain&nbsp;Environment&nbsp;Output|Shader_terrainenvironmentoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. Terrain normal vectors may be sent to the '''N'''<sub>1</sub>, '''N'''<sub>2</sub>, and '''N'''<sub>3</sub> input ports in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process.}} |} == See Also == * [[Material Editor]] [[Category:Shaders]] 8647f8730f3c96ba617b9584bac30e0b4009dd32 Basic Shader Processes 0 427 660 551 2025-01-06T03:09:44Z Eric Lengyel 1 wikitext text/x-wiki This is a list of the basic shader processes that are available in the [[Shader Editor]] under the Basic tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Constant Scalar|Shader_constantscalar.png|None|Scalar|Outputs a constant scalar value that is specified in the settings for the process. A ''parameter slot'' may be specified in the process settings. If the parameter slot is set to &ldquo;Constant&rdquo; (the default), then the output of this process can never be changed while rendering. However, if one of the eight numbered parameter slots is selected, then it is possible to change the value output by this process without actually modifying the shader. For instance, the Set Shader Parameter script method can be used to change the output value of this process, effectively making it a variable parameter of the shader.}} |- {{Process|Constant Vector|Shader_constantvector.png|None|4D vector|Outputs a constant vector value that is specified in the settings for the process. See the note about parameter slots under the Constant Scalar process.}} |- {{Process|Constant Color|Shader_constantcolor.png|None|RGBA color|Outputs a constant color value that is specified in the settings for the process. This color has components in the range 0 to 1, and it typically represents reflective colors. See the note about parameter slots under the Constant Scalar process.}} |- {{Process|Constant Luminance|Shader_constantluminance.png|None|RGBA color|Outputs a constant luminance value that is specified in the settings for the process. This luminance has unlimited range, and it typically represents lighting or emissive colors. See the note about parameter slots under the Constant Scalar process.}} |- {{Process|Shader Time|Shader_time.png|None|Scalar|Outputs a scalar value in the range [0,1) representing the current shader time. The shader time runs from 0 to 1 over a period of 120 seconds and then repeats by wrapping back to 0.}} |- {{Process|Fragment Depth|Shader_fragmentdepth.png|None|Scalar|Outputs a scalar value equal to the depth of the fragment in camera space.}} |- {{Process|Primitive Facing|Shader_primitivefacing.png|None|Scalar|Outputs a scalar value that is +1.0 for front-facing primitives and &minus;1.0 for back-facing primitives.}} |- {{Process|Merge 2D|Shader_merge2d.png|Scalar '''x''' (required), Scalar '''y''' (required)|2D vector|Combines the two scalar inputs '''x''' and '''y''' into a single 2D vector output.}} |- {{Process|Merge 3D|Shader_merge3d.png|Scalar '''x''' (required), Scalar '''y''' (required), Scalar '''z''' (required)|3D vector|Combines the three scalar inputs '''x''', '''y''', and '''z''' into a single 3D vector output.}} |- {{Process|Merge 4D|Shader_merge4d.png|Scalar '''x''' (required), Scalar '''y''' (required), Scalar '''z''' (required), Scalar '''w''' (required)|4D vector|Combines the four scalar inputs '''x''', '''y''', '''z''', and '''w''' into a single 4D vector output.}} |- {{Process|Texture Map|Shader_texturemap.png|2D or 3D vector '''TEXC''' (required), scalar '''BIAS''' (optional)|RGBA color|Samples a texture map using the input texture coordinates '''TEXC'''. The texture map is specified in the settings for the process. The size of the input '''TEXC''' is determined by the type of the texture map. The input is a 2D vector for 2D and Rect textures, and the size is a 3D vector for 3D, Cube, and Array 2D textures. If the '''BIAS''' input is connected, then it's value is added to the mipmap index calculated by the hardware. Note that this process should not be used for normal maps. Use the Normal Map process instead.}} |- {{Process|Normal Map|Shader_normalmap.png|2D vector '''TEXC''' (required), scalar '''BIAS''' (optional)|3D vector|Samples a normal map using the input texture coordinates '''TEXC'''. The normal map is specified in the settings for the process. If the '''BIAS''' input is connected, then it's value is added to the mipmap index calculated by the hardware.}} |- {{Process|Paint Texture|Shader_painttexture.png|2D vector '''TEXC''' (required)|RGBA color|Samples a paint space texture map using the input texture coordinates '''TEXC'''. The texture map is determined by what paint space is associated with the geometry being rendered. The input vector is normally the output of the Paint Texcoord [[Interpolant Shader Processes|interpolant process]].}} |- {{Process|Terrain Texture|Shader_terraintexture.png|None|RGBA color|Samples a terrain texture palette. The texture map is specified in the settings for the process. Note that this process should not be used for terrain normal maps. Use the Terrain Normal process instead.}} |- {{Process|Terrain Normal 1, 2, 3|Shader_terrainnormal1.png|None|3D vector|Samples a terrain normal palette. The normal map is specified in the settings for the process. If one of these three processes exists, then all three should exist and should use the same normal map. Their outputs should be sent to a Terrain Diffuse Reflection and/or Terrain Specular Reflection process.}} |- {{Process|Impostor Texture|Shader_impostortexture.png|None|RGBA color|Samples an impostor texture map. The texture map is specified in the settings for the process. Note that this process should not be used for impostor normal maps. Use the Impostor Normal process instead.}} |- {{Process|Impostor Normal|Shader_impostornormal.png|None|3D vector|Samples an impostor normal map. The normal map is specified in the settings for the process.}} |} == See Also == * [[Shader Editor]] * [[Mathematical Shader Processes]] * [[Complex Shader Processes]] * [[Interpolant Shader Processes]] [[Category:Shaders]] 772d5edc03a600d3a139ae509bcf4604b4db9f8b 662 660 2025-01-06T03:13:00Z Eric Lengyel 1 wikitext text/x-wiki This is a list of the basic shader processes that are available in the [[Shader Editor]] under the Basic tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Constant Scalar|Shader_constantscalar.png|None|Scalar|Outputs a constant scalar value that is specified in the settings for the process. A ''parameter slot'' may be specified in the process settings. If the parameter slot is set to &ldquo;Constant&rdquo; (the default), then the output of this process can never be changed while rendering. However, if one of the eight numbered parameter slots is selected, then it is possible to change the value output by this process without actually modifying the shader. For instance, the Set Shader Parameter script method can be used to change the output value of this process, effectively making it a variable parameter of the shader.}} |- {{Process|Constant Vector|Shader_constantvector.png|None|4D vector|Outputs a constant vector value that is specified in the settings for the process. See the note about parameter slots under the Constant Scalar process.}} |- {{Process|Constant Color|Shader_constantcolor.png|None|RGBA color|Outputs a constant color value that is specified in the settings for the process. This color has components in the range 0 to 1, and it typically represents reflective colors. See the note about parameter slots under the Constant Scalar process.}} |- {{Process|Constant Luminance|Shader_constantluminance.png|None|RGBA color|Outputs a constant luminance value that is specified in the settings for the process. This luminance has unlimited range, and it typically represents lighting or emissive colors. See the note about parameter slots under the Constant Scalar process.}} |- {{Process|Shader Time|Shader_time.png|None|Scalar|Outputs a scalar value in the range [0,1) representing the current shader time. The shader time runs from 0 to 1 over a period of 120 seconds and then repeats by wrapping back to 0.}} |- {{Process|Fragment Depth|Shader_fragmentdepth.png|None|Scalar|Outputs a scalar value equal to the depth of the fragment in camera space.}} |- {{Process|Primitive Facing|Shader_primitivefacing.png|None|Scalar|Outputs a scalar value that is +1.0 for front-facing primitives and &minus;1.0 for back-facing primitives.}} |- {{Process|Merge 2D|Shader_merge2d.png|Scalar '''x''' (required), Scalar '''y''' (required)|2D vector|Combines the two scalar inputs '''x''' and '''y''' into a single 2D vector output.}} |- {{Process|Merge 3D|Shader_merge3d.png|Scalar '''x''' (required), Scalar '''y''' (required), Scalar '''z''' (required)|3D vector|Combines the three scalar inputs '''x''', '''y''', and '''z''' into a single 3D vector output.}} |- {{Process|Merge 4D|Shader_merge4d.png|Scalar '''x''' (required), Scalar '''y''' (required), Scalar '''z''' (required), Scalar '''w''' (required)|4D vector|Combines the four scalar inputs '''x''', '''y''', '''z''', and '''w''' into a single 4D vector output.}} |- {{Process|Texture Map|Shader_texturemap.png|2D or 3D vector '''TEXC''' (required), scalar '''BIAS''' (optional)|RGBA color|Samples a texture map using the input texture coordinates '''TEXC'''. The texture map is specified in the settings for the process. The size of the input '''TEXC''' is determined by the type of the texture map. The input is a 2D vector for 2D and Rect textures, and the size is a 3D vector for 3D, Cube, and Array 2D textures. If the '''BIAS''' input is connected, then it's value is added to the mipmap index calculated by the hardware. Note that this process should not be used for normal maps. Use the Normal Map process instead.}} |- {{Process|Normal Map|Shader_normalmap.png|2D vector '''TEXC''' (required), scalar '''BIAS''' (optional)|3D vector|Samples a normal map using the input texture coordinates '''TEXC'''. The normal map is specified in the settings for the process. If the '''BIAS''' input is connected, then it's value is added to the mipmap index calculated by the hardware.}} |- {{Process|Paint Texture|Shader_painttexture.png|2D vector '''TEXC''' (required)|RGBA color|Samples a paint space texture map using the input texture coordinates '''TEXC'''. The texture map is determined by what paint space is associated with the geometry being rendered. The input vector is normally the output of the Paint Texcoord [[Interpolant Shader Processes|interpolant process]].}} |- {{Process|Terrain Texture|Shader_terraintexture.png|None|RGBA color|Samples a terrain texture palette. The texture map is specified in the settings for the process. Note that this process should not be used for terrain normal maps. Use the Terrain Normal process instead.}} |- {{Process|Terrain Normal 1, 2, 3|Shader_terrainnormal1.png|None|3D vector|Samples a terrain normal palette. The normal map is specified in the settings for the process. If one of these three processes exists, then all three should exist and should use the same normal map. Their outputs should be used as inputs for the Terrain Diffuse Reflection, Terrain Specular Reflection, and Terrain Environment Output processes.}} |- {{Process|Impostor Texture|Shader_impostortexture.png|None|RGBA color|Samples an impostor texture map. The texture map is specified in the settings for the process. Note that this process should not be used for impostor normal maps. Use the Impostor Normal process instead.}} |- {{Process|Impostor Normal|Shader_impostornormal.png|None|3D vector|Samples an impostor normal map. The normal map is specified in the settings for the process.}} |} == See Also == * [[Shader Editor]] * [[Mathematical Shader Processes]] * [[Complex Shader Processes]] * [[Interpolant Shader Processes]] [[Category:Shaders]] d468664870c71a342f1abb63a47cf727c297ff6f File:Shader composite.png 6 247 663 249 2025-01-06T03:14:22Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader composite.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader glyph.png 6 270 664 272 2025-01-06T03:22:02Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shader glyph.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Complex Shader Processes 0 429 665 580 2025-01-06T03:22:09Z Eric Lengyel 1 wikitext text/x-wiki This is a list of the complex shader processes that are available in the [[Shader Editor]] under the Complex tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Diffuse Reflection|Shader_diffuse.png|Tangent-space normal '''N''' (optional)|Scalar|Calculates the Lambertian diffuse reflection factor '''N'''&nbsp;&middot;&nbsp;'''L''', where '''L''' is the tangent-space direction to light. The result is saturated to the range [0,1]. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Specular Reflection|Shader_specular.png|Tangent-space normal '''N''' (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor ('''N'''&nbsp;&middot;&nbsp;'''H''')<sup>''p''</sup>, where '''H''' is the tangent-space direction halfway between the direction to light and direction to viewer. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). The specular power ''p'' controls the sharpness of the specularity. This process implicitly uses the tangent halfway direction interpolant, which in turn uses the tangent light direction and tangent view direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Terrain Diffuse Reflection|Shader_terraindiffuse.png|Terrain normal '''N'''<sub>1</sub> (optional), Terrain normal '''N'''<sub>2</sub> (optional), Terrain normal '''N'''<sub>3</sub> (optional)|Scalar|Calculates the Lambertian diffuse reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Terrain Specular Reflection|Shader_terrainspecular.png|Terrain normal '''N'''<sub>1</sub> (optional), Terrain normal '''N'''<sub>2</sub> (optional), Terrain normal '''N'''<sub>3</sub> (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. The specular power ''p'' controls the sharpness of the specularity. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Combine Normal Maps|Shader_combinenormals.png|Normal vector '''N'''<sub>1</sub> (required), Normal vector '''N'''<sub>2</sub> (required), Scalar ''t'' (optional)|3D vector|If ''t'' is omitted, calculates a new normal vector corresponding to the normal that would be produced if the two height maps producing the input normals were added together. If ''t'' is not omitted, then it determines how the heights are weighted, with the height corresponding to '''N'''<sub>1</sub> being weighted most when ''t'' is zero and the height corresponding to '''N'''<sub>2</sub> being weighted most when ''t'' is one. A value for ''t'' of 0.5 produces an average height, which is not the same as the sum produces when ''t'' is omitted.}} |- {{Process|Reflect Vector|Shader_reflectvector.png|3D vector '''V''' (required), 3D vector '''N''' (optional)|3D vector|Calculates the reflection of the vector '''V''' across the vector '''N'''. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).}} |- {{Process|Smooth Parameter|Shader_smooth.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 3''t''<sup>2</sup>&nbsp;&minus;&nbsp;2''t''<sup>3</sup> componentwise. This has the effect of smoothing an interpolation parameter within the range [0,1] since the derivative at both endpoints is zero.}} |- {{Process|Steep Parameter|Shader_steep.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 2''t''&nbsp;&minus;&nbsp;''t''<sup>2</sup> componentwise. This has the effect of making an interpolation start quickly at a steep slope and finish smoothly.}} |- {{Process|Linear Ramp|Shader_linearramp.png|Value '''A''' (required)|Value of size matching '''A'''|Remaps the range [''c''&nbsp;&minus;&nbsp;&frac12;''w'',&nbsp;''c''&nbsp;+&nbsp;&frac12;''w''] to the range [0,1] componentwise, where ''c'' is a center value and ''w'' is the width of the input range. The values of ''c'' and ''w'' are specified in the settings for the process.}} |- {{Process|Delta Depth|Shader_deltadepth.png|None|Scalar|Outputs the difference between the depth of the geometry in the structure buffer and the depth of the fragment being shaded, scaled by a factor ''s'' and clamped to the range [0,1]. The scale factor ''s'' is specified in the settings for the process. If rendering to the structure buffer is disabled, then the output value is always 1.0.}} |- {{Process|Tangent to World Transform|Shader_tangenttoworld.png|3D vector '''V''' (required)|3D vector|Transforms the vector '''V''' from tangent space coordinates into world space coordinates. This process implicitly uses three 3D vector interpolants containing the matrix that transforms from tangent space to world space.}} |- {{Process|Parallax Offset|Shader_parallax.png|2D vector '''TEXC''' (required)|2D vector|Perturbs the input texture coordinates using the parallax information in the normal map and outputs the result. The normal map is specified in the settings for the process. If parallax mapping is disabled, then the input texture coordinates '''TEXC''' are simply passed through to the output. This process implicitly uses the tangent view direction interpolant.}} |- {{Process|Horizon Shadow|Shader_horizon.png|2D vector '''TEXC''' (required), RGB color '''RGB''' (required)|RGB color|Calculates the horizon map shadowing based on the two input horizon map sampled at the texture coordinates '''TEXC''' and multiplies the input color '''RGB''' by the amount of light reaching the surface. The horizon map is specified in the settings for the process. Flags for excluding horizon mapping for infinite or points lights can also be set. If horizon mapping is disabled or the shader is used in conjunction with a light type that has been excluded, then the input color '''RGB''' is simply passed through to the output. This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Kill Fragment|Shader_kill.png|Scalar '''A''' (required), Scalar '''B''' (optional)|None|Kills the current fragment if '''A''' &lt; '''B'''. If '''B''' is omitted, then the fragment is killed if '''A''' &lt; 0.}} |- {{Process|Render Glyph|Shader_glyph.png|2D vector '''TEXC''' (required), RGBA color '''RGBA''' (required)|RGBA color|Renders glyph or vector graphics with Slug. The '''TEXC''' input should use the Texcoord 2 interpolant, and the '''RGBA''' input would normally use the Vertex Color interpolant.}} |- {{Process|Composite Buffer|Shader_composite.png|None|RGBA color|Samples from the composite buffer at the current fragment coordinates.}} |} == See Also == * [[Shader Editor]] * [[Basic Shader Processes]] * [[Mathematical Shader Processes]] * [[Interpolant Shader Processes]] [[Category:Shaders]] 93009604139998669b86a210ca13a6103db699da 667 665 2025-01-06T03:46:56Z Eric Lengyel 1 wikitext text/x-wiki This is a list of the complex shader processes that are available in the [[Shader Editor]] under the Complex tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Diffuse Reflection|Shader_diffuse.png|Tangent-space normal '''N''' (optional)|Scalar|Calculates the Lambertian diffuse reflection factor '''N'''&nbsp;&middot;&nbsp;'''L''', where '''L''' is the tangent-space direction to light. The result is saturated to the range [0,1]. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Specular Reflection|Shader_specular.png|Tangent-space normal '''N''' (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor ('''N'''&nbsp;&middot;&nbsp;'''H''')<sup>''p''</sup>, where '''H''' is the tangent-space direction halfway between the direction to light and direction to viewer. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). The specular power ''p'' controls the sharpness of the specularity. This process implicitly uses the tangent halfway direction interpolant, which in turn uses the tangent light direction and tangent view direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Terrain Diffuse Reflection|Shader_terraindiffuse.png|Terrain normal '''N'''<sub>1</sub> (optional), Terrain normal '''N'''<sub>2</sub> (optional), Terrain normal '''N'''<sub>3</sub> (optional)|Scalar|Calculates the Lambertian diffuse reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Terrain Specular Reflection|Shader_terrainspecular.png|Terrain normal '''N'''<sub>1</sub> (optional), Terrain normal '''N'''<sub>2</sub> (optional), Terrain normal '''N'''<sub>3</sub> (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. The specular power ''p'' controls the sharpness of the specularity. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Combine Normal Maps|Shader_combinenormals.png|Normal vector '''N'''<sub>1</sub> (required), Normal vector '''N'''<sub>2</sub> (required), Scalar ''t'' (optional)|3D vector|If ''t'' is omitted, calculates a new normal vector corresponding to the normal that would be produced if the two height maps producing the input normals were added together. If ''t'' is not omitted, then it determines how the heights are weighted, with the height corresponding to '''N'''<sub>1</sub> being weighted most when ''t'' is zero and the height corresponding to '''N'''<sub>2</sub> being weighted most when ''t'' is one. A value for ''t'' of 0.5 produces an average height, which is not the same as the sum produces when ''t'' is omitted.}} |- {{Process|Reflect Vector|Shader_reflectvector.png|3D vector '''V''' (required), 3D vector '''N''' (optional)|3D vector|Calculates the reflection of the vector '''V''' across the vector '''N'''. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).}} |- {{Process|Smooth Parameter|Shader_smooth.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 3''t''<sup>2</sup>&nbsp;&minus;&nbsp;2''t''<sup>3</sup> componentwise. This has the effect of smoothing an interpolation parameter within the range [0,1] since the derivative at both endpoints is zero.}} |- {{Process|Steep Parameter|Shader_steep.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 2''t''&nbsp;&minus;&nbsp;''t''<sup>2</sup> componentwise. This has the effect of making an interpolation start quickly at a steep slope and finish smoothly.}} |- {{Process|Linear Ramp|Shader_linearramp.png|Value '''A''' (required)|Value of size matching '''A'''|Remaps the range [''c''&nbsp;&minus;&nbsp;&frac12;''w'',&nbsp;''c''&nbsp;+&nbsp;&frac12;''w''] to the range [0,1] componentwise, where ''c'' is a center value and ''w'' is the width of the input range. The values of ''c'' and ''w'' are specified in the settings for the process.}} |- {{Process|Delta Depth|Shader_deltadepth.png|None|Scalar|Outputs the difference between the depth of the geometry in the structure buffer and the depth of the fragment being shaded, scaled by a factor ''s'' and clamped to the range [0,1]. The scale factor ''s'' is specified in the settings for the process. If rendering to the structure buffer is disabled, then the output value is always 1.0.}} |- {{Process|Tangent to World Transform|Shader_tangenttoworld.png|3D vector '''V''' (required)|3D vector|Transforms the vector '''V''' from tangent space coordinates into world space coordinates. This process implicitly uses three 3D vector interpolants containing the matrix that transforms from tangent space to world space.}} |- {{Process|Parallax Offset|Shader_parallax.png|2D vector '''TEXC''' (required)|2D vector|Perturbs the input texture coordinates using the parallax information in the normal map and outputs the result. The normal map is specified in the settings for the process. If parallax mapping is disabled, then the input texture coordinates '''TEXC''' are simply passed through to the output. This process implicitly uses the tangent view direction interpolant.}} |- {{Process|Horizon Shadow|Shader_horizon.png|2D vector '''TEXC''' (required), RGB color '''RGB''' (required)|RGB color|Calculates the horizon map shadowing based on the two input horizon map sampled at the texture coordinates '''TEXC''' and multiplies the input color '''RGB''' by the amount of light reaching the surface. The horizon map is specified in the settings for the process. Flags for excluding horizon mapping for infinite or points lights can also be set. If horizon mapping is disabled or the shader is used in conjunction with a light type that has been excluded, then the input color '''RGB''' is simply passed through to the output. This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Kill Fragment|Shader_kill.png|Scalar '''A''' (required), Scalar '''B''' (optional)|None|Kills the current fragment if '''A''' &lt; '''B'''. If '''B''' is omitted, then the fragment is killed if '''A''' &lt; 0.}} |- {{Process|Render Glyph|Shader_glyph.png|2D vector '''TEXC''' (required), RGBA color '''RGBA''' (required)|RGBA color|Renders glyph or vector graphics with Slug. The '''TEXC''' input should use the Texcoord 2 interpolant, and the '''RGBA''' input would normally use the Vertex Color interpolant.}} |- {{Process|Composite Buffer|Shader_composite.png|None|RGBA color|Samples from the composite buffer at the current fragment coordinates.}} |- {{Process|Generate Impostor Normal / Depth|Shader_genimpostor.png|3D vector '''N''' (optional)|RGBA color|When impostor textures are being generated, this process outputs the impostor normal in the RGB channels, and it outputs the impostor depth in the alpha channel.}} |} == See Also == * [[Shader Editor]] * [[Basic Shader Processes]] * [[Mathematical Shader Processes]] * [[Interpolant Shader Processes]] [[Category:Shaders]] 1027df8c4582ac9522fc4a9c0523364eb2240199 670 667 2025-01-06T04:03:40Z Eric Lengyel 1 wikitext text/x-wiki This is a list of the complex shader processes that are available in the [[Shader Editor]] under the Complex tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Diffuse Reflection|Shader_diffuse.png|Tangent-space normal '''N''' (optional)|Scalar|Calculates the Lambertian diffuse reflection factor '''N'''&nbsp;&middot;&nbsp;'''L''', where '''L''' is the tangent-space direction to light. The result is saturated to the range [0,1] and divided by pi. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Specular Reflection|Shader_specular.png|Tangent-space normal '''N''' (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor sat('''N'''&nbsp;&middot;&nbsp;'''H''')<sup>''p''</sup>, where '''H''' is the tangent-space direction halfway between the direction to light and direction to viewer. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). The specular power ''p'' controls the sharpness of the specularity. This process implicitly uses the tangent halfway direction interpolant, which in turn uses the tangent light direction and tangent view direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Diffuse Transflection|Shader_transflection.png|Tangent-space normal '''N''' (optional)|Scalar|Calculates the diffuse transflection factor '''N'''&nbsp;&middot;&nbsp;'''L''', where '''L''' is the tangent-space direction to light. The result is multiplied by the front-facing factor ''f'' and divided by pi, and it is ''not'' saturated. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Specular Transmission|Shader_transmission.png|Specular power ''p'' (required)|Scalar|Calculates the specular transmission factor sat(&minus;'''L'''&nbsp;&middot;&nbsp;'''V''')<sup>''p''</sup>, where '''L''' and '''V''' are the tangent-space direction to light and direction to viewer. The specular power ''p'' controls the sharpness of the specularity. This produces a transmission strength when a material is viewed from the back side with respect to the incoming light. This process implicitly uses the tangent light direction and view direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Terrain Diffuse Reflection|Shader_terraindiffuse.png|Terrain normal '''N'''<sub>1</sub> (optional), Terrain normal '''N'''<sub>2</sub> (optional), Terrain normal '''N'''<sub>3</sub> (optional)|Scalar|Calculates the Lambertian diffuse reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Terrain Specular Reflection|Shader_terrainspecular.png|Terrain normal '''N'''<sub>1</sub> (optional), Terrain normal '''N'''<sub>2</sub> (optional), Terrain normal '''N'''<sub>3</sub> (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. The specular power ''p'' controls the sharpness of the specularity. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Combine Normal Maps|Shader_combinenormals.png|Normal vector '''N'''<sub>1</sub> (required), Normal vector '''N'''<sub>2</sub> (required), Scalar ''t'' (optional)|3D vector|If ''t'' is omitted, calculates a new normal vector corresponding to the normal that would be produced if the two height maps producing the input normals were added together. If ''t'' is not omitted, then it determines how the heights are weighted, with the height corresponding to '''N'''<sub>1</sub> being weighted most when ''t'' is zero and the height corresponding to '''N'''<sub>2</sub> being weighted most when ''t'' is one. A value for ''t'' of 0.5 produces an average height, which is not the same as the sum produces when ''t'' is omitted.}} |- {{Process|Reflect Vector|Shader_reflectvector.png|3D vector '''V''' (required), 3D vector '''N''' (optional)|3D vector|Calculates the reflection of the vector '''V''' across the vector '''N'''. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).}} |- {{Process|Smooth Parameter|Shader_smooth.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 3''t''<sup>2</sup>&nbsp;&minus;&nbsp;2''t''<sup>3</sup> componentwise. This has the effect of smoothing an interpolation parameter within the range [0,1] since the derivative at both endpoints is zero.}} |- {{Process|Steep Parameter|Shader_steep.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 2''t''&nbsp;&minus;&nbsp;''t''<sup>2</sup> componentwise. This has the effect of making an interpolation start quickly at a steep slope and finish smoothly.}} |- {{Process|Linear Ramp|Shader_linearramp.png|Value '''A''' (required)|Value of size matching '''A'''|Remaps the range [''c''&nbsp;&minus;&nbsp;&frac12;''w'',&nbsp;''c''&nbsp;+&nbsp;&frac12;''w''] to the range [0,1] componentwise, where ''c'' is a center value and ''w'' is the width of the input range. The values of ''c'' and ''w'' are specified in the settings for the process.}} |- {{Process|Delta Depth|Shader_deltadepth.png|None|Scalar|Outputs the difference between the depth of the geometry in the structure buffer and the depth of the fragment being shaded, scaled by a factor ''s'' and clamped to the range [0,1]. The scale factor ''s'' is specified in the settings for the process. If rendering to the structure buffer is disabled, then the output value is always 1.0.}} |- {{Process|Tangent to World Transform|Shader_tangenttoworld.png|3D vector '''V''' (required)|3D vector|Transforms the vector '''V''' from tangent space coordinates into world space coordinates. This process implicitly uses three 3D vector interpolants containing the matrix that transforms from tangent space to world space.}} |- {{Process|Parallax Offset|Shader_parallax.png|2D vector '''TEXC''' (required)|2D vector|Perturbs the input texture coordinates using the parallax information in the normal map and outputs the result. The normal map is specified in the settings for the process. If parallax mapping is disabled, then the input texture coordinates '''TEXC''' are simply passed through to the output. This process implicitly uses the tangent view direction interpolant.}} |- {{Process|Horizon Shadow|Shader_horizon.png|2D vector '''TEXC''' (required), RGB color '''RGB''' (required)|RGB color|Calculates the horizon map shadowing based on the two input horizon map sampled at the texture coordinates '''TEXC''' and multiplies the input color '''RGB''' by the amount of light reaching the surface. The horizon map is specified in the settings for the process. Flags for excluding horizon mapping for infinite or points lights can also be set. If horizon mapping is disabled or the shader is used in conjunction with a light type that has been excluded, then the input color '''RGB''' is simply passed through to the output. This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Kill Fragment|Shader_kill.png|Scalar '''A''' (required), Scalar '''B''' (optional)|None|Kills the current fragment if '''A''' &lt; '''B'''. If '''B''' is omitted, then the fragment is killed if '''A''' &lt; 0.}} |- {{Process|Render Glyph|Shader_glyph.png|2D vector '''TEXC''' (required), RGBA color '''RGBA''' (required)|RGBA color|Renders glyph or vector graphics with Slug. The '''TEXC''' input should use the Texcoord 2 interpolant, and the '''RGBA''' input would normally use the Vertex Color interpolant.}} |- {{Process|Composite Buffer|Shader_composite.png|None|RGBA color|Samples from the composite buffer at the current fragment coordinates.}} |- {{Process|Generate Impostor Normal / Depth|Shader_genimpostor.png|3D vector '''N''' (optional)|RGBA color|When impostor textures are being generated, this process outputs the impostor normal in the RGB channels, and it outputs the impostor depth in the alpha channel.}} |} == See Also == * [[Shader Editor]] * [[Basic Shader Processes]] * [[Mathematical Shader Processes]] * [[Interpolant Shader Processes]] [[Category:Shaders]] 1b7d1cce7daed35769fcae02c36ff39dc62b6ca6 671 670 2025-01-06T04:14:51Z Eric Lengyel 1 wikitext text/x-wiki This is a list of the complex shader processes that are available in the [[Shader Editor]] under the Complex tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Diffuse Reflection|Shader_diffuse.png|World-space or tangent-space normal '''N''' (optional)|Scalar|Calculates the Lambertian diffuse reflection factor '''N'''&nbsp;&middot;&nbsp;'''L''', where '''L''' is the direction to light. The result is saturated to the range [0,1] and divided by pi. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). This process implicitly uses the world light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Specular Reflection|Shader_specular.png|World-space or tangent-space normal '''N''' (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor sat('''N'''&nbsp;&middot;&nbsp;'''H''')<sup>''p''</sup>, where '''H''' is the direction halfway between the direction to light and direction to viewer. If '''N''' is omitted, then it's as if '''N''' is (0,0,1) in tangent space. The specular power ''p'' controls the sharpness of the specularity. This process implicitly uses the world halfway direction interpolant, which in turn uses the world light direction and world view direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Diffuse Transflection|Shader_transflection.png|World-space or tangent-space normal '''N''' (optional)|Scalar|Calculates the diffuse transflection factor '''N'''&nbsp;&middot;&nbsp;'''L''', where '''L''' is the direction to light. The result is multiplied by the front-facing factor ''f'' and divided by pi, and it is ''not'' saturated. If '''N''' is omitted, then it's as if '''N''' is (0,0,1) in tangent space. This process implicitly uses the world light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Specular Transmission|Shader_transmission.png|Specular power ''p'' (required)|Scalar|Calculates the specular transmission factor sat(&minus;'''L'''&nbsp;&middot;&nbsp;'''V''')<sup>''p''</sup>, where '''L''' and '''V''' are the direction to light and direction to viewer. The specular power ''p'' controls the sharpness of the specularity. This produces a transmission strength when a material is viewed from the back side with respect to the incoming light. This process implicitly uses the world light direction and view direction interpolants. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Terrain Diffuse Reflection|Shader_terraindiffuse.png|Terrain normal '''N'''<sub>1</sub> (optional), Terrain normal '''N'''<sub>2</sub> (optional), Terrain normal '''N'''<sub>3</sub> (optional)|Scalar|Calculates the Lambertian diffuse reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Terrain Specular Reflection|Shader_terrainspecular.png|Terrain normal '''N'''<sub>1</sub> (optional), Terrain normal '''N'''<sub>2</sub> (optional), Terrain normal '''N'''<sub>3</sub> (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. The specular power ''p'' controls the sharpness of the specularity. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Combine Normal Maps|Shader_combinenormals.png|Normal vector '''N'''<sub>1</sub> (required), Normal vector '''N'''<sub>2</sub> (required), Scalar ''t'' (optional)|3D vector|If ''t'' is omitted, calculates a new normal vector corresponding to the normal that would be produced if the two height maps producing the input normals were added together. If ''t'' is not omitted, then it determines how the heights are weighted, with the height corresponding to '''N'''<sub>1</sub> being weighted most when ''t'' is zero and the height corresponding to '''N'''<sub>2</sub> being weighted most when ''t'' is one. A value for ''t'' of 0.5 produces an average height, which is not the same as the sum produces when ''t'' is omitted.}} |- {{Process|Reflect Vector|Shader_reflectvector.png|3D vector '''V''' (required), 3D vector '''N''' (optional)|3D vector|Calculates the reflection of the vector '''V''' across the vector '''N'''. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).}} |- {{Process|Smooth Parameter|Shader_smooth.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 3''t''<sup>2</sup>&nbsp;&minus;&nbsp;2''t''<sup>3</sup> componentwise. This has the effect of smoothing an interpolation parameter within the range [0,1] since the derivative at both endpoints is zero.}} |- {{Process|Steep Parameter|Shader_steep.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 2''t''&nbsp;&minus;&nbsp;''t''<sup>2</sup> componentwise. This has the effect of making an interpolation start quickly at a steep slope and finish smoothly.}} |- {{Process|Linear Ramp|Shader_linearramp.png|Value '''A''' (required)|Value of size matching '''A'''|Remaps the range [''c''&nbsp;&minus;&nbsp;&frac12;''w'',&nbsp;''c''&nbsp;+&nbsp;&frac12;''w''] to the range [0,1] componentwise, where ''c'' is a center value and ''w'' is the width of the input range. The values of ''c'' and ''w'' are specified in the settings for the process.}} |- {{Process|Delta Depth|Shader_deltadepth.png|None|Scalar|Outputs the difference between the depth of the geometry in the structure buffer and the depth of the fragment being shaded, scaled by a factor ''s'' and clamped to the range [0,1]. The scale factor ''s'' is specified in the settings for the process. If rendering to the structure buffer is disabled, then the output value is always 1.0.}} |- {{Process|Tangent to World Transform|Shader_tangenttoworld.png|3D vector '''V''' (required)|3D vector|Transforms the vector '''V''' from tangent space coordinates into world space coordinates. This process implicitly uses three 3D vector interpolants containing the matrix that transforms from tangent space to world space.}} |- {{Process|Parallax Offset|Shader_parallax.png|2D vector '''TEXC''' (required)|2D vector|Perturbs the input texture coordinates using the parallax information in the normal map and outputs the result. The normal map is specified in the settings for the process. If parallax mapping is disabled, then the input texture coordinates '''TEXC''' are simply passed through to the output. This process implicitly uses the tangent view direction interpolant.}} |- {{Process|Horizon Shadow|Shader_horizon.png|2D vector '''TEXC''' (required), RGB color '''RGB''' (required)|RGB color|Calculates the horizon map shadowing based on the two input horizon map sampled at the texture coordinates '''TEXC''' and multiplies the input color '''RGB''' by the amount of light reaching the surface. The horizon map is specified in the settings for the process. Flags for excluding horizon mapping for infinite or points lights can also be set. If horizon mapping is disabled or the shader is used in conjunction with a light type that has been excluded, then the input color '''RGB''' is simply passed through to the output. This process implicitly uses the tangent light direction interpolant. If the ambient reflection output depends on this process, then the results are undefined.}} |- {{Process|Kill Fragment|Shader_kill.png|Scalar '''A''' (required), Scalar '''B''' (optional)|None|Kills the current fragment if '''A''' &lt; '''B'''. If '''B''' is omitted, then the fragment is killed if '''A''' &lt; 0.}} |- {{Process|Render Glyph|Shader_glyph.png|2D vector '''TEXC''' (required), RGBA color '''RGBA''' (required)|RGBA color|Renders glyph or vector graphics with Slug. The '''TEXC''' input should use the Texcoord 2 interpolant, and the '''RGBA''' input would normally use the Vertex Color interpolant.}} |- {{Process|Composite Buffer|Shader_composite.png|None|RGBA color|Samples from the composite buffer at the current fragment coordinates.}} |- {{Process|Generate Impostor Normal / Depth|Shader_genimpostor.png|3D vector '''N''' (optional)|RGBA color|When impostor textures are being generated, this process outputs the impostor normal in the RGB channels, and it outputs the impostor depth in the alpha channel.}} |} == See Also == * [[Shader Editor]] * [[Basic Shader Processes]] * [[Mathematical Shader Processes]] * [[Interpolant Shader Processes]] [[Category:Shaders]] 9a8badcf5e1c3e61efba4ac455f0667a14281b77 File:Shader genimpostor.png 6 530 666 2025-01-06T03:46:50Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader transflection.png 6 531 668 2025-01-06T03:48:52Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shader transmission.png 6 532 669 2025-01-06T03:49:04Z Eric Lengyel 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:Shadereditor.png 6 353 673 355 2025-01-06T04:28:13Z Eric Lengyel 1 Eric Lengyel uploaded a new version of [[File:Shadereditor.png]] wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Mathematical Shader Processes 0 428 675 646 2025-01-06T06:21:59Z Eric Lengyel 1 wikitext text/x-wiki This is a list of the mathematical shader processes that are available in the [[Shader Editor]] under the Math tab. {| {{Table}} {{Tablehead|Process|Description}} |- {{Process|Absolute Value|Shader_abs.png|Value '''A'''|Value of size matching '''A'''|Calculates the absolute value of each component of the input '''A'''.}} |- {{Process|Add|Shader_add.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise sum of the inputs '''A''' and '''B'''.}} |- {{Process|Average|Shader_avg.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise average of the inputs '''A''' and '''B'''.}} |- {{Process|Cosine|Shader_cos.png|Scalar '''A'''|Scalar|Calculates the cosine of the input '''A''', where the input is measured in radians.}} |- {{Process|Cross Product|Shader_xpd.png|3D vectors '''A''' and '''B'''|3D vector|Calculates the cross product of the inputs '''A''' and '''B'''. If one of the input vectors is in tangent space and the other is in world space, then additional shader code is generated to transform the tangent-space vector into world space before the cross product is evaluated.}} |- {{Process|Divide|Shader_div.png|Value '''A''', Scalar '''B'''|Value of size matching '''A'''|Calculates the quotient of each component of the input '''A''' and the scalar input '''B'''. ''Tip:'' If you're dividing by a constant value, then it would be more efficient to multiply by the reciprocal of the constant. For example, you should multiply by 0.5 instead of dividing by 2.0.}} |- {{Process|Dot Product 3D|Shader_dp3.png|3D vectors '''A''' and '''B'''|Scalar|Calculates the dot product of the inputs '''A''' and '''B'''. If one of the input vectors is in tangent space and the other is in world space, then additional shader code is generated to transform the tangent-space vector into world space before the dot product is evaluated.}} |- {{Process|Dot Product 4D|Shader_dp4.png|4D vectors '''A''' and '''B'''|Scalar|Calculates the dot product of the inputs '''A''' and '''B'''.}} |- {{Process|Exp Base 2|Shader_ex2.png|Scalar '''A'''|Scalar|Calculates 2 raised to the power given by the input '''A'''.}} |- {{Process|Expand|Shader_expand.png|Value '''A'''|Value of size matching '''A'''|Multiplies each component of the input '''A''' by 2.0 and then subtracts 1.0.}} |- {{Process|Floor|Shader_flr.png|Value '''A'''|Value of size matching '''A'''|Calculates the floor of each component of the input '''A'''. To calculate a ceiling, negate the input and output of the Floor process.}} |- {{Process|Fraction|Shader_frc.png|Value '''A'''|Value of size matching '''A'''|Calculates the fraction of each component of the input '''A'''. The fraction of a number is the difference between that number and its floor.}} |- {{Process|Invert|Shader_invert.png|Value '''A'''|Value of size matching '''A'''|Subtracts each component of the input '''A''' from 1.0.}} |- {{Process|Linear Interpolate|Shader_lrp.png|Values '''A''', '''B''', and '''t'''|Value of size matching largest of '''A''', '''B''', and '''t'''|Calculates the linear interpolation between the components of '''A''' and '''B''' using the components of the input '''t''' as the interpolation parameter.}} |- {{Process|Log Base 2|Shader_lg2.png|Scalar '''A'''|Scalar|Calculates the logarithm base 2 of the input '''A'''. If the input is not positive, then the result is undefined.}} |- {{Process|Magnitude 3D|Shader_magnitude3d.png|3D vector '''A'''|Scalar|Calculates the magnitude of the input '''A'''.}} |- {{Process|Maximum|Shader_max.png|Values '''A''' and '''B''' (required), value '''C''' (optional)|Value of size matching larger of '''A''', '''B''', and '''C'''|Calculates the componentwise maximum of the inputs '''A''', '''B''', and '''C'''. If input '''C''' is omitted, then the maximum of only '''A''' and '''B''' is calculated.}} |- {{Process|Minimum|Shader_min.png|Values '''A''' and '''B''' (required), value '''C''' (optional)|Value of size matching larger of '''A''', '''B''', and '''C'''|Calculates the componentwise minimum of the inputs '''A''', '''B''', and '''C'''. If input '''C''' is omitted, then the minimum of only '''A''' and '''B''' is calculated.}} |- {{Process|Multiply|Shader_mul.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise product of the inputs '''A''' and '''B'''.}} |- {{Process|Multiply Add|Shader_mad.png|Values '''A''', '''B''', and '''C'''|Value of size matching largest of '''A''', '''B''', and '''C'''|Calculates the componentwise product of the inputs '''A''' and '''B''' and then adds the components of the input '''C'''.}} |- {{Process|Normalize 3D|Shader_normalize3d.png|3D vector '''A'''|3D vector|Normalizes the input '''A'''. If the input is the zero vector, then the result is undefined.}} |- {{Process|Power|Shader_pow.png|Scalars '''A''' and '''B'''|Scalar|Calculates the input '''A''' raised to the power of the input '''B'''. If the input '''A''' is negative, then the result is undefined. If the input '''A''' is zero and the input '''B''' is not positive, then the result is undefined. ''Tip:'' If you're just squaring a value, then it would be more efficient to multiply the value by itself. That is, you should calculate '''A'''&nbsp;&times;&nbsp;'''A''' using the '''Multiply''' process instead of raising '''A''' to the power of 2.}} |- {{Process|Reciprocal|Shader_rcp.png|Scalar '''A'''|Scalar|Calculates the reciprocal of the input '''A'''. If the input is zero, then the result is undefined.}} |- {{Process|Reciprocal Square Root|Shader_rsq.png|Scalar '''A'''|Scalar|Calculates the reciprocal square root of the input '''A'''. If the input is not positive, then the result is undefined.}} |- {{Process|Round|Shader_round.png|Value '''A'''|Value of size matching '''A'''|Rounds each component of the input '''A''' to the nearest integer.}} |- {{Process|Saturate|Shader_sat.png|Value '''A'''|Value of size matching '''A'''|Clamps each component of the input '''A''' to the range [0,1].}} |- {{Process|Set if Equal|Shader_seq.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set if Greater Equal|Shader_sge.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is greater than or equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set if Greater Than|Shader_sgt.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is greater than the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set if Less Equal|Shader_sle.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is less than or equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set of Less Than|Shader_slt.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is less than the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Set if Not Equal|Shader_sne.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is not equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}} |- {{Process|Sine|Shader_sin.png|Scalar '''A'''|Scalar|Calculates the sine of the input '''A''', where the input is measured in radians.}} |- {{Process|Square Root|Shader_sqrt.png|Scalar '''A'''|Scalar|Calculates the square root of the input '''A'''. If the input is negative, then the result is undefined.}} |- {{Process|Subtract|Shader_sub.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise difference of the inputs '''A''' and '''B'''.}} |- {{Process|Sum of Products|Shader_sumproducts.png|Values '''A''', '''B''', '''C''', and '''D'''|Value of size matching largest of '''A''', '''B''', '''C''', and '''D'''|Calculates the componentwise products of the inputs '''A''' and '''B''' and the componentwise products of the inputs '''C''' and '''D''' and then calculates the componentwise sum of the results.}} |} == See Also == * [[Shader Editor]] * [[Basic Shader Processes]] * [[Complex Shader Processes]] * [[Interpolant Shader Processes]] [[Category:Shaders]] bacd569680bb513bc61ba92604f2538e0f9fdec3